私が架空のアートストアをいくつかのモデルで運営していると想像してみてください(モデルでは、ヌードモデルのようにアート用語ではなくRails用語を参照しています)。
class Artwork < ActiveRecord::Base
belongs_to :purchase
belongs_to :artist
end
class Purchase < ActiveRecord::Base
has_many :artworks
belongs_to :customer
end
が作成され、Artwork
しばらくしてからに含まれPurchase
ます。私のcreate
またはupdate
コントローラーメソッドでは、新しいものを既存Purchase
のものに関連付けたいと思います。Purchase
Artwork
Artwork
が存在しなかった場合、私は@purchase.artworks.build
またはを行うことができ@purchase.artworks.create
ましたが、これらは両方とも、私がそうではない新しいものを作成していることを前提としてArtwork
います。次のようなもので既存のアートワークを追加できます。
params[:artwork_ids].each do |artwork|
@purchase.artworks << Artwork.find(artwork)
end
ただし、これはトランザクションではありません。データベースはすぐに更新されます。(もちろん、私がcreate
コントローラーにいる場合を除いて、@purchase
呼び出すまでは存在しないため、「トランザクション」で実行される可能性があると思いますsave
が、それは役に立ちません。)メソッドupdate
もありますが、@purchase.artwork_ids=
同様に即時です。
このようなものでうまくいくと思いますupdate
が、とても上品ではありません。
@purchase = Purchase.find(params[:id])
result = @purchase.transaction do
@purchase.update_attributes(params[:purchase])
params[:artwork_ids].each do |artwork|
artwork.purchase = @purchase
artwork.save!
end
end
これに従来の方法が続きます。
if result
redirect_to purchase_url(@purchase), notice: 'Purchase was successfully updated.' }
else
render action: "edit"
end
私が探しているのはaccepts_nested_attributes_for
、モデルを入れてから呼び出すだけでresult = @artwork.save
、すべてが魔法のように機能するという、他の方向からの動作のようなものです。