如何在 Rails 中使用插入所有方法,包括关联?

Posted

技术标签:

【中文标题】如何在 Rails 中使用插入所有方法,包括关联?【英文标题】:How to use insert all method including associations in Rails? 【发布时间】:2021-12-19 21:35:35 【问题描述】:

我有 Article、Category 和 CategoryArticle 模型

# models/article.rb
Article < ApplicationRecord
  has_many :category_articles
  has_many :categories, through: :category_articles
end

# models/category.rb
Category < ApplicationRecord
  has_many :category_articles
  has_many :articles, through: :category_articles
end

# models/category.rb
CategoryArticle < ApplicationRecord
  belongs_to :category
  belongs_to :article
end

我想做的是插入具有各自类别的文章集合,例如:

article = Article.new
article.created_at = Time.zone.now
article.updated_at = Time.zone.now

article_collection = []
article_collection << article.as_json(:except => :id)       

Article.insert_all(article)

上面的代码对我有用,但是当我想插入关联时,我收到如下错误:

未知关键字:: 类别

因为我从 json 插入整个集合,它不将类别识别为属性

最终,以下工作:

irb(main):029:0> article_collection
=> 
["id"=>nil,
  "name"=>"example",
  "created_at"=>"2021-11-05T22:19:55.850Z",
  "updated_at"=>"2021-11-05T22:20:05.481Z"]

Article.insert_all(文章)

但是当我想安装类别集合时这不起作用:

  irb(main):029:0> article_collection
  => 
  ["id"=>nil,
   "name"=>"example",
   "created_at"=>"2021-11-05T22:19:55.850Z",
   "updated_at"=>"2021-11-05T22:20:05.481Z",
   "categories"=>["id"=>1, "name"=>"Whisky", "created_at"=>"2021-11- 
                   05T18:07:05.737Z",  "updated_at"=>"2021-11-05T18:07:05.737Z"]]

Article.insert_all(article)
=> unknown attribute 'categories' for Article

如果您能告诉我如何使用 insert_all 进行多重关联,我将不胜感激

【问题讨论】:

尝试在 Article 类中设置 accepts_nested_attributes_for :categories 并将 categories 键重命名为带有数据的哈希中的 categories_attributes,这样 rails 应该知道如何处理关联 api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/…跨度> 如果它对我有用,但是在执行 insert_all 或 upsert_all 方法时,它无法识别 categories_attribute 以及我如何需要它在单个查询中进行多次插入 我刚刚注意到类别是通过关联的has_many,而不是简单的has_many,我不认为你可以在1次插入中做你想做的事。我会将其拆分为首先保存所有类别,然后使用带有所有类别 ID 的 categories_ids 键保存所有文章,我认为这样可以工作 我去试试,非常感谢你的时间:D 【参考方案1】:

insert_allupdate_alldestroy_all 等。不要像您可能期望在 Active Record 实例上使用的其他方法一样工作。因为它们是为批量操作而设计的,所以不会创建模型的实例,您传递的参数只是直接简化为单个 SQL INSERT 语句。 https://apidock.com/rails/v6.0.0/ActiveRecord/Persistence/ClassMethods/insert_all

这意味着您可能希望执行的许多操作都行不通,例如没有观察者或事件(例如,没有after_create after_save 被insert_all 触发。accept_nested_attributes 在这张图片中无法工作,它们无法简化为单个 SQL INSERT 语句。

所以我建议为此使用create

【讨论】:

以上是关于如何在 Rails 中使用插入所有方法,包括关联?的主要内容,如果未能解决你的问题,请参考以下文章

如何在Rails 5中删除模型时删除模型的所有关联

在 Rails 中连接关联的按钮不起作用。所有权转让

如何正确销毁 ruby​​ on rails 中的关联记录?

如何在 Rails 2.3.8 中使用带有关联的 Active 脚手架列出活动记录?

Rails - 验证关联的存在?

Rails 关联不存在。更好的方法?