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

Ruby on rails 如何以及在何处处理相关记录的更新过程?,ruby-on-rails,ruby,activerecord,model,controller,Ruby On Rails,Ruby,Activerecord,Model,Controller,我使用的是RubyonRails4,我希望通过update\u attributes方法正确处理相关记录的更新和创建过程。也就是说,我有以下几点: # Model class Article < ActiveRecord::Base has_many :categories accepts_nested_attributes_for :categories end # Controller class ArticlesController < ApplicationCon

我使用的是RubyonRails4,我希望通过
update\u 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", "..."=>"..."}, : "..." => {...}}
  ...
#模型
类文章[:name,…])
结束
结束
#更新请求的记录器
已启动修补程序“/文章/6”
ArticlesController的处理#更新
参数:{“utf8”=>“✓", "文章“=>{”标题“=>”样本标题“,”类别属性“=>{”0“=>{”名称“=>”样本类别1“,”…”=>”,“…”,”1“=>{”名称“=>”样本类别2“,“…”,“…”=>”,:“…”=>{…}
...
这个问题与Rails处理更新数据库中相关记录的方式有关,在我的例子中,通过
@article
对象更新类别时:当提交数据以便触发
更新
操作时,参数被传递到
更新属性
方法(如上面的记录器所示)然后Rails在数据库中创建新的类别记录,哈希
categories\u属性中的每个元素都有一个类别记录

但是,我的目的是更新现有的类别记录(如果存在),或者创建新的类别记录(如果不存在),以确保
类别
数据库表中
文章id
名称
列的唯一性,可能会搜索这些列中存在的数据,以检查其是否为needed用于更新或创建新记录。事实上,在“编辑文章”视图中,我显示了一个表单,其中包含用于编辑类别的输入字段,包括预填充与现有类别相关的数据的字段,以及可由编辑用户“动态”创建的类别的空字段


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

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

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

如果你想销毁带有嵌套参数的类别,你还需要添加
:\u destroy
。它们有完整的故事。

你应该在
文章
模型中添加
类别属性
作为
属性
。比如:

attr_accessible :categories_attributes

如果没有这一行,您将不可避免地面临上述问题,即创建新记录而不是更新现有记录。此外,还有一个名为
nested_form
的gem,它在构建这些复杂表单方面做得非常好。

您尝试过吗?@karlingen-我应该在哪里尝试运行该方法?在model或controller中?@karlingen-我尝试过d“第一个或第一个创建”在很多方面,也许这不是我用来解决问题的最佳方法……我阅读了Rails指南,尝试使用
:id
,但它没有解决问题,即使是更新/创建问题。此外,我问自己:
:id
为什么必要?我可以通过运行
@article.categories
。我自己对细节有点不清楚。:)我知道的是:
permit
中未明确列出的所有参数在传递到
update\u attributes
之前都会被删除。如果在该阶段缺少
:id
,则无法知道应该更新哪个类别,相反,它们都会被删除我喜欢新的类别。当我遇到类似问题时,我从服务器日志中复制了原始参数,并将它们与
require
permit
之后剩下的参数进行了比较。也许可以在控制台中使用
强参数
提供帮助。如果您愿意,我们也可以继续深入研究。我认为问题与Stro无关ngParameters…但是,“我们也可以继续在聊天中挖掘”。@user502052是我创建的。关于转到聊天是否是一个好主意还存在争议,但我觉得如果我们在这里反映出任何突破,它会很好。
attr\u accessible
默认为,替换为。您的答案适用于Rails 3和更早版本。