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

Posted

技术标签:

【中文标题】如何以及在哪里处理关联记录的更新过程?【英文标题】:How and where to handle the updating process of associated records? 【发布时间】:2013-11-28 14:24:52 【问题描述】:

我正在使用 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 中存在的每个元素创建一个。

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

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

【问题讨论】:

你试过了吗? apidock.com/rails/ActiveRecord/Relation/first_or_create @karlingen - 我应该在哪里尝试运行该方法?在模型或控制器中? @karlingen - 我以多种方式尝试了“first_or_create”,也许这不是我可以用来解决问题的 ritgh 方法... 【参考方案1】:

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

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

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

【讨论】:

我阅读了 Rails Guides 和 API Documentation 并尝试使用 :id 但它没有解决问题,即使是更新/创建问题。此外,我问自己:为什么:id 是必要的?我可以通过运行@article.categories 来检索类别。 我自己对细节有点不清楚。 :) 这就是我所知道的:在permit 中未明确列出的所有参数在传递给update_attributes 之前都会被删除。如果在那个阶段缺少:id,则无法知道应该更新哪个类别,相反,它们看起来都像是新类别。 当我遇到类似问题时,我从服务器日志中复制了原始参数,并将它们与requirepermit 之后剩下的参数进行了比较。也许these examples 可以帮助在控制台中使用strong_parameters。如果你愿意,我们也可以继续挖掘chat。 我认为问题与StrongParameters无关......但是,“我们也可以在聊天中继续挖掘”。 @user502052 我创建了a room。有some confusion关于移动聊天是否是一个好主意,但我觉得如果我们在这里反映任何突破就可以了。【参考方案2】:

您应该在 Article 模型中添加 categories_attributesattr_accessible。喜欢:

attr_accessible :categories_attributes

如果没有这条线,您肯定会面临上述问题,即创建新记录而不是更新现有记录。还有一个名为 nested_form 的 gem,它在构建这些复杂的表单方面做得非常出色。

【讨论】:

attr_accessible默认为not used in Rails 4,替换为Strong Parameters。不过,您的答案对 Rails 3 及更早版本有效。

以上是关于如何以及在哪里处理关联记录的更新过程?的主要内容,如果未能解决你的问题,请参考以下文章

Grails批量处理锁定在桌子上

软删除的存储过程

什么是过程和更新以及它在primefaces中的工作方式[重复]

mysql存储过程嵌套循环并分页处理数据

db2如何创建存储过程

如何使用 VBA 执行插入/更新记录的存储过程?