扶手:我怎样一个事务协会的has_many添加到现有的模式? [英] Rails: How do I transactionally add a has_many association to an existing model?
问题描述
让我们想象一下我运行一个虚构的艺术商店与一对夫妇模型(和模型,我指的是Rails的任期不艺术期限作为裸体模特),看起来是这样的:
Let's imagine I run an imaginary art store with a couple models (and by models I'm referring to the Rails term not the arts term as in nude models) that looks something like this:
class Artwork < ActiveRecord::Base
belongs_to :purchase
belongs_to :artist
end
class Purchase < ActiveRecord::Base
has_many :artworks
belongs_to :customer
end
的艺术品
创建并晚些时候它被包含在购买
。在我的创建
或为
我会喜欢新的关联购买更新
控制器方法购买
与现有艺术品
。
The Artwork
is created and sometime later it is included in a Purchase
. In my create
or update
controller method for Purchase
I would like to associate the new Purchase
with the existing Artwork
.
如果在艺术品
不存在,我可以做的 @ purchase.artworks.build
或 @ purchase.artworks.create
,但这些都假设我要创建一个新的艺术品
而我不是。我可以像这样加上现有的艺术作品:
If the Artwork
did not exist I could do @purchase.artworks.build
or @purchase.artworks.create
, but these both assume that I'm creating a new Artwork
which I am not. I could add the existing artwork with something like this:
params[:artwork_ids].each do |artwork|
@purchase.artworks << Artwork.find(artwork)
end
然而,这不是事务。该数据库立即更新。 (当然,除非我在创建
控制器,在这种情况下,我认为它可能会做事务性,因为 @purchase
不存在,直到我称之为保存
,但这并不能帮我换更新
)。有也是 @ purchase.artwork_ids =
的方法,但这是直接为好。
However, this isn't transactional. The database is updated immediately. (Unless of course I'm in the create
controller in which case I think it may be done "transactionally" since the @purchase
doesn't exist until I call save
, but that doesn't help me for update
.) There is also the @purchase.artwork_ids=
method, but that is immediate as well.
我觉得这样的事情会在更新
操作工作,但它是非常不雅。
I think something like this will work for the update
action, but it is very inelegant.
@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
在我的模型的另一个方向,然后调用结果= @ artwork.save
,一切工作就像魔术。
What I'm looking for is something like the way it would work from the other direction where I could just put accepts_nested_attributes_for
in my model and then call result = @artwork.save
and everything works like magic.
推荐答案
我已经想出了一个办法做我想要的相当优雅。我需要进行更新,我的产品
MVC的各个部分。
I have figured out a way to do what I want which fairly elegant. I needed to make updates to each part of my Product
MVC.
型号:
attr_accessible: artwork_ids
我不得不添加artwork_ids到attr_accessible,因为它不包括之前
I had to add artwork_ids to attr_accessible since it wasn't included before.
查看:
= check_box_tag "purchase[artwork_ids][]", artwork.id, artwork.purchase == @purchase
在我看来,我有一个数组与 check_box_tag
每个艺术品。我不能使用 check_box
因为疑难杂症的地方没有检查框会导致真正的隐藏价值,而不是被发送的作品ID的。然而,这给我留下了从采购删除所有作品的问题。当执行更新
,如果我取消每个复选框,然后在 PARAMS [:购买]
散列不会有:artwork_ids
输入
In my view I have an array for each artwork with a check_box_tag
. I couldn't use check_box
because of the gotcha where not checking the box would cause a hidden value of "true" to be sent instead of an artwork id. However, this leaves me with the problem of deleting all the artwork from a purchase. When doing update
, if I uncheck each check box, then the params[:purchase]
hash won't have an :artwork_ids
entry.
控制器:
params[:purchase][:artwork_ids] ||= []
添加此保证的值被设置,并且将具有除去所有现存的关联的所期望的效果。但是,这会导致一个讨厌失败的RSpec Purchase.any_instance.should_receive(:update_attributes方法)。随着({'这些'=&GT;'参数'})
失败,因为:update_attributes方法
实际收到的 {这些=&gt;中PARAMS,artwork_ids=&GT; []})
。我试图在视图中设置一个 hidden_value_tag
代替,但不能让它开始工作。我觉得这尼特是值得一个新的问题。
Adding this guarantees that the value is set, and will have the desired effect of removing all existing associations. However, this causes a pesky rspec failure
Purchase.any_instance.should_receive(:update_attributes).with({'these' => 'params'})
fails because :update_attributes
actually received {"these"=>"params", "artwork_ids"=>[]})
. I tried setting a hidden_value_tag
in the view instead, but couldn't get it to work. I think this nit is worthy of a new question.
这篇关于扶手:我怎样一个事务协会的has_many添加到现有的模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!