32

Rails 3.2+では、これを行うことができます:

SomeModel.some_scope.first_or_initialize

つまり、次のこともできます。

OtherModel.some_models.first_or_initialize

これはかなり便利だと思いますが、関連付けにfirst_or_buildメソッドが必要です。これは、必要に応じて関連付けに新しいレコードを追加するように機能します。has_manyfirst_or_initializebuild

明確化のための更新first_or_initialize:はい、私はとについて知っていfirst_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

あなたが望むことを正確に実行するものがレールに組み込まれているかどうかはわかりませんが、現在使用しているよりも簡潔な拡張機能を使用して 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 に答える