前提条件
したがって、次のモデルがあるとします。
class Company < ActiveRecord::Base belongs_to :location has_one :user accepts_nested_attributes_for :user accepts_nested_attrbiutes_for :location end class User < ActiveRecord::Base belongs_to :company end class Location < ActiveRecord::Base has_one :company end
ユーザーと場所のリソースがネストされた会社フォームが必要です。 一見すると、コードは次のように見えるかもしれません:
form_for :company do |f| f.text_field :name f.fields_for :user, f.object.user_or_build do |fu| fu.text_field :name end f.fields_for :location, f.object.location_or_build do |fl| fl.text_field :address end end
目的の形状を表示するには十分です。 しかし、これはそうではありません。 アプリケーションを起動してブラウザーを開くと、ページ上の予想される3つのフィールドではなく、たった1つのことがわかります-これは会社の名前フィールドです(次のような初期化されたオブジェクトがあると仮定します:
)@company = Company.new
このコードの何が問題になっていますか?
問題は、@ companyの関連するユーザーおよびロケーションオブジェクトを初期化していないことです。
@company.build_location # @company.location = Location.new @company.build_user # @company.user = User.new
field_forヘルパーが実行される前にこれらの条件が満たされると、フォームは期待どおりになります。 ただし、コントローラーをクリーンにする必要があるため、コントローラーで毎回そのようなコードを記述することは、どういうわけか深刻ではありません!
解決策
この問題は、このgemの助けを借りて回避することができます。gemの名前はやや厄介です-get_or_buildです。
Gemfileに次の行を追加します。
gem 'get_ot_build'
gemのインストール:バンドルインストール、アプリケーションの再起動、fields_forヘルパーのリファクタリングを次のように行います。
form_for :company do |f| f.fields_for :user, :build_association => true do |fu| fu.text_field :name end f.fields_for :user, :build_association => true do |fl| fl.text_field :address end end
その後、ユーザーと場所の関連付けオブジェクトの初期化コードは、コントローラー、テンプレート、およびヘルパー(他の場所にあります)から削除でき、不要になります)。
批判とコメントに非常に感謝します。宝石の開発のボランティアも大歓迎です。 ご清聴ありがとうございました!