如何在 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_all
和 update_all
和 destroy_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 中使用插入所有方法,包括关联?的主要内容,如果未能解决你的问题,请参考以下文章
如何正确销毁 ruby on rails 中的关联记录?