Rails 4更新嵌套属性

更新嵌套属性追加而不是更新有许多关系我试图使用Rails 4 Update_attributes

Class Person <ActiveRecord::Base has_many :pets accepts_nested_attributes_for :pets end Class Pet < ActiveRecord::Base belongs_to :person end 

在我的控制器中,我正在接受params为{id:23,house_no:’22A’,pets:[{name:’jeffy’,type:’dog’},{name:’sharky’,type:’fish’} ]}

我的更新方法是

 def update @Person = Person.find(params[:id]) if @Person.update(person_params) @Person.save render 'persons/create', status 200 else render 'persons/create', status 400 end end private def person_params person_params = params.permit(:house_no) person_params.merge! ({pets_attributes: params[:pets]}) if params[:pets].present? person_params end 

现在,当我更新它并且如果该人已经有宠物时,则新宠物被附加而不是更新,例如,如果身份1的人有1只名为“老虎”的宠物并且我用2只名为“Shasha”的宠物更新该人“Monti”然后人物记录有3只宠物(Tiger,Shasha和Monti)而不是更新为2(Shasha和Monti)

看手册:

http://api.rubyonrails.org/v4.0.1/classes/ActiveRecord/NestedAttributes/ClassMethods.html

你需要发送你的属性,如pets_attributes:[{name:'jeffy', type:'dog'}, {name:'sharky', type:'fish'}]

它应该工作正常。

请阅读

您现在可以通过成员的属性哈希在关联的post上设置或更新属性:包括键:posts_attributes,其中包含一系列post属性的哈希作为值。对于没有id键的每个哈希,新记录将实例化,除非哈希还包含一个计算结果为true的_destroy键。

更新Person模型如下:

 class Person < ActiveRecord::Base ## NOTE: class (c lowercase) and NOT Class has_many :pets accepts_nested_attributes_for :pets, allow_destroy: true ## Added allow_destroy end 

为了通过属性哈希破坏关联模型,即Pet ,您必须首先使用:allow_destroy选项启用它。

然后,从您的视图中,您需要为要删除的宠物传递_destroy属性。

因为,您还没有共享视图特定代码。 以下是如何在您的视图中实现它的示例。 根据您的要求更改:

 <%= form_for @person do |f| %> <%## .. %> <%= f.fields_for :pets do |builder| %> <%## .. %> <%= builder.check_box :_destroy %> <%= builder.label :_destroy, "Remove Pet" %> <% end %> <% end %> 

在上面的代码中,您需要添加checkboxlabel以传递_destroy值。

在此之后,更新控制器中的person_params方法,如下所示:

 def person_params params.require(:person).permit(:house_no, pets_attributes: [:id, :name, :type, :person_id, :_destroy]) end 

注意:

应该使用大写名称定义instance variables 。 大写的名称用于在Ruby声明Constants

 def update @person = Person.find(params[:id]) if @person.update(person_params) @person.save render 'persons/create', status 200 else render 'persons/create', status 400 end end 

您可以尝试在person_params :id属性添加到:pets_attributes数组吗?

您需要允许id属性。

可能1.你想要分开分配宠物,

 @Person.pets = Pets.find(params[:pets]) 

或者2.在保存人员之前清除宠物。

 @Person.pets.destroy 

尝试将person_params更改为

 def person_params person_params = params.require(:person).permit(:house_no ,pets_attributes: [:name,:type]) end 

并从更新方法中删除@person.save 。您不需要它。并且还使用! update

 def update @Person = Person.find(params[:id]) if @Person.update!(person_params) render 'persons/create', status 200 else render 'persons/create', status 400 end end 

更新

而且,正如我所看到的, Pet模型中没有belongs_to :person关联,在模型中添加它

 Class Pet < ActiveRecord::Base belongs_to :person end 

现在允许person_id属性通过在params添加它

 def person_params person_params = params.require(:person).permit(:house_no,pets_attributes: [:name,:type,:person_id]) end 

您需要使用pets_attributes编辑params

还需要在pet对象中添加:id参数。