我正在使用Ruby on Rails 4,我想通过update_attributes
方法正确处理相关记录的更新和创建过程。也就是说,我有以下内容:
# Model
class Article < ActiveRecord::Base
has_many :categories
accepts_nested_attributes_for :categories
end
# Controller
class ArticlesController < ApplicationController
def update
@article = Article.find(params[:id])
@article.update_attributes(update_params)
...
end
private
def update_params
params.require(:article).permit(:title, ..., :categories_attributes => [: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
中存在的每个元素。
但是,我的目的是更新现有的类别记录(如果存在的话,或者如果那些不存在则创建新的),相应article_id
和name
列的唯一性在categories
数据库表中,可能会搜索这些列中的数据,以检查是否需要更新或创建新记录。事实上,在“编辑文章”视图中,我显示了一个表单,其中包含用于编辑类别的输入字段,包括预先填充了与现有类别相关的数据的字段和可以由编辑器用户“即时”创建的类别的空字段。
如何正确处理此行为?它是模型还是控制器的责任?或者,是否有更好的方法直接在“编辑文章”视图中管理类别?
答案 0 :(得分:0)
我认为你需要允许嵌套模型的:id
属性:
def update_params
params.require(:article).permit(
:title,
...,
:categories_attributes => [:id, :name, ...]
)
end
如果您希望能够使用嵌套参数销毁类别,则还需要添加:_destroy
。 Rails Guides有完整的故事。
答案 1 :(得分:0)
您应该在categories_attributes
模型中添加attr_accessible
Article
。像:
attr_accessible :categories_attributes
如果没有这一行,您将面临上述问题,创建新记录而不是更新现有记录。还有一个名为nested_form
的宝石,它可以很好地构建这些复杂的形式。