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

时间:2013-11-28 14:24:53

标签: ruby-on-rails ruby activerecord model controller

我正在使用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_idname列的唯一性在categories数据库表中,可能会搜索这些列中的数据,以检查是否需要更新或创建新记录。事实上,在“编辑文章”视图中,我显示了一个表单,其中包含用于编辑类别的输入字段,包括预先填充了与现有类别相关的数据的字段和可以由编辑器用户“即时”创建的类别的空字段。

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

2 个答案:

答案 0 :(得分:0)

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

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

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

答案 1 :(得分:0)

您应该在categories_attributes模型中添加attr_accessible Article。像:

attr_accessible :categories_attributes

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