32

在 rails 3.2+ 中,您可以这样做:

SomeModel.some_scope.first_or_initialize

这意味着您还可以执行以下操作:

OtherModel.some_models.first_or_initialize

我发现这非常有用,但我想first_or_build在我的关联上有一个方法has_many,它的作用就像first_or_initialize但也会在需要时向关联添加一条新记录build

更新澄清:是的,我知道first_or_initializefirst_or_create。问题是,first_or_initialize不会将初始化的记录添加到关联的目标build中,并且first_or_create......好吧......创建一个记录,这不是意图。

我有一个有效的解决方案,使用关联扩展:

class OtherModel < ActiveRecord::Base

  has_many :some_models do 
    def first_or_build( attributes = {}, options = {}, &block )
      object = first_or_initialize( attributes, options, &block )
      proxy_association.add_to_target( object ) if object.new_record?
      object
    end
  end

end

我只是想知道是否:

  • 这个问题的内置解决方案已经存在?
  • 我的实现有我看不到的缺陷?
4

1 回答 1

22

我不确定 Rails 中是否有任何内置的东西可以完全满足您的需求,但是您可以使用比您当前使用的更简洁的扩展来模仿 first_or_initialize 代码,我相信它可以满足您的需求,并将其包装成一个可重用的扩展,如下所示。这是用 Rails 3.2 扩展格式编写的。

module FirstOrBuild
  def first_or_build(attributes = nil, options = {}, &block)
    first || build(attributes, options, &block)
  end
end

class OtherModel < ActiveRecord::Base
  has_many :some_models, :extend => FirstOrBuild
end
于 2013-09-10T16:37:29.930 回答