如何以及在何处处理相关记录的更新过程?

我正在使用Ruby on Rails 4,我想通过update_attributes方法正确处理相关记录的更新和创建过程。 也就是说,我有以下几点:

 # Model class Article < ActiveRecord::Base has_many :categories accepts_nested_attributes_for :categories end # Controller class ArticlesController  [:name, ...]) end end # Logger for the update request Started PATCH "/articles/6" Processing by ArticlesController#update Parameters: {"utf8"=>"✓", "article"=>{"title"=>"Sample title", "categories_attributes"=>{"0"=>{"name"=>"Sample Category 1", "..."=>"..."}, "1"=>{"name"=>"Sample Category 2", "..."=>"..."}, : "..." => {...}} ... 

该问题与Rails处理更新数据库中相关记录的方式有关,在我的情况下,通过@article对象更新类别时:提交数据时触发update操作,并将参数传递给update_attributes方法(如在上面的记录器中显示)然后Rails在数据库中创建新的类别记录,一个用于散列categories_attributes存在的每个元素。

但是, 我的目的是更新现有类别记录(如果存在)或创建新类别记录(如果不存在) ,相应于categories数据库表中article_idname列的唯一性,可能会按顺序搜索这些列中存在的数据检查是否需要更新或创建新记录。 事实上,在“编辑文章”视图中,我显示了一个表单,其中包含用于编辑类别的输入字段,包括预先填充了与现有类别相关的数据的字段,以及可由编辑器用户“即时”创建的类别的空字段。

我该如何正确处理这种行为? 它是模型还是控制器的责任? 或者,是否有更好的方法直接在“编辑文章”视图中管理类别?

我相信你需要为你的嵌套模型允许:id属性:

 def update_params params.require(:article).permit( :title, ..., :categories_attributes => [:id, :name, ...] ) end 

如果您希望能够使用嵌套参数销毁类别,则还需要添加:_destroy 。 Rails指南有完整的故事。

您应该在Article模型中将categories_attributes添加为attr_accessible 。 喜欢:

 attr_accessible :categories_attributes 

如果没有这一行,您将面临上述问题,创建新记录而不是更新现有记录。 还有一个名为nested_form的gem,它可以很好地构建这些复杂的表单。