这看起来应该非常简单。我想设置#accepts_nested_attributes_for,这样当我使用为子类设置的任何非空参数保存父类时,它会删除其中没有被参数中的id直接引用的任何其他子项。
出于某种原因,我真的很难找到一种合理的方法来做到这一点。
真的。
我有一个模特,承诺:
class Pledge < ActiveRecord::Base
has_many :companies, dependent: :destroy
accepts_nested_attributes_for :companies
# Other stuff
end
相应的公司型号:
class Company < ActiveRecord::Base
belongs_to :pledge
end
假设我已经在pledge_a上保存了company_1(id:1,name:company_1),然后我致电pledge_.update(params)
,其中params
要么没有引用公司ID,因此:
{
"someotherval"=>"5",
"id"=>"10",
"companies_attributes"=>
{
"0"=>
{
"name"=>"company_2"
}
}
}
或(完全如上,但是)对于相关公司的ID不同:
{
"someotherval"=>"5",
"id"=>"10",
"companies_attributes"=>
{
"0"=>
{
"id"=>"2"
"name"=>"company_2"
}
}
}
指示Rails的最简单方法是删除任何不包含在参数中的公司,即每当我在嵌套参数中与任何现有公司调用#update时创建一个新组合? / p>
我尝试过很多事情:
在Pledge上使用before_save挂钩删除公司 - 在公司被保存之后,这似乎删除了他们所以我总是以无公司承诺结束
通过将:reject_if块添加到一行的accepts_nested_attributes_然后将其用于destroy_all_companies after_save hook来构建公司数组 - 这没有用,因为在某些时候Rails似乎重新初始化了承诺,所以当我们碰到钩子时,阵列已经消失了
在我调用#update删除公司之前在控制器中编写一些代码 - 这是我被贬低的黑客,但它是可怕的。首先,如果我通过不包含任何嵌套公司参数的参数,我总是不想删除这些公司。其次,我必须通过参数并删除任何非空的公司#id值,否则当Rails无法找到有问题的公司时会爆炸。第三,如果验证失败且承诺没有更新,我现在已经删除了所有公司。
必须有一个更健全的方法来做到这一点......对吗?
答案 0 :(得分:1)
给出您要销毁的公司的列表,例如:
companies_to_destroy = @pledge.companies.reject do |company|
pledge_params[:companies_attributes]
.map { |attrs| attrs[:id] }
.include? company.id
end
正如@gabrielhilal的评论所建议的那样,您可以在allow_destroy: true
中使用accepts_nested_attributes_for
,然后将每个要销毁的公司添加到companies_attributes数组{ id: 'x', _destroy: '1' }
中。
或者,您可以致电您要销毁的公司mark_for_destruction。
在任何一种情况下,当您致电保证书时,销毁公司都将被销毁。