仅遍历持久对象

Iterating through only persisted objects

这是我创建显示的代码:

def create
    @display = @department.displays.new(display_params)
    @token = @display.build_token(value: (max_token + 1) , status: 0)

    if @display.save
        ....
end

max_token是调用显示token中最大数量token的方法

def max_token
  @tokens = @department.displays.map do |display|
    display.token.value
  end
  @tokens.max
end


问题

我已经使用 create 方法中的代码为部门创建了一个新显示。

@display = @department.displays.new(display_params)

但是还没有保存,因为@display.save是在max_token之后调用的方法。

但是调用max_token方法时,代码

@tokens = @department.displays.map do |display|

还在显示部门未保存的显示。

并且由于尚未设置显示的令牌,因为它未保存,因此抛出 nil 值 错误。

我的解决方案

这是我目前尝试的方法,但我想知道是否有更好的方法。

def max_token
      @tokens = @department.displays.map do |display|
        if display.token.nil?
          display.token.value
        else
          0
        end
      end
      @tokens.max
    end

尝试先创建一个新的分隔 Display,然后在调用 max_token 后将其分配给 @department,这样新的 Display 就不会包含在 @department.displays.map

def create
    @display = Displays.new(display_params)
    @token = @display.build_token(value: (max_token + 1) , status: 0)
    @department.displays << @display        

    if @display.save
        ....
end

如果您不担心 value 在 DB 层的唯一性,您可以简单地过滤掉 tokennil 值的显示:

def max_token
  @department.displays.where.not(token: nil).map do |display|
    display.token.value
  end.max
end

(这还假设您实际上不需要分配 @tokens 作为 max_token 的副作用。)