私が架空のアートストアをいくつかのモデルで運営していると想像してみてください(モデルでは、ヌードモデルのようにアート用語ではなく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のものに関連付けたいと思います。PurchaseArtwork
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、すべてが魔法のように機能するという、他の方向からの動作のようなものです。