简体   繁体   English

update_all方法不适用于关联记录

[英]update_all method not working for associated records

I have two models and the association between them is has_and_belongs_to_many . 我有两个模型,它们之间的关联是has_and_belongs_to_many I need to refactor the code as it causes n + 1 queries. 我需要重构代码,因为它会导致n + 1个查询。

Problem: n+1 queries 问题:n + 1个查询

1. Task 1.任务

    class Task < ActiveRecord::Base
      has_and_belongs_to_many :user_groups
    end

2. UserGroup 2.用户组

    class UserGroup < ActiveRecord::Base
      has_and_belongs_to_many :tasks
    end

Requirement: 需求:

Assign Tasks to user_groups 将任务分配给user_groups

Previous Controller Code: 以前的控制器代码:

task_ids.each do |task_id|
 find(task_id).update_attributes! user_group_ids: params[:user_group_ids], release_date: params[:release_date]
end

My Attempt: 我的尝试:

tasks = Task.where(id: task_ids)
tasks.update_all(user_group_ids: params[:user_group_ids], release_date: params[:release_date])

Error: 错误:

ActiveRecord::StatementInvalid (PG::UndefinedColumn: ERROR: column "user_group_ids" of relation "tasks" does not exist ActiveRecord :: StatementInvalid(PG :: UndefinedColumn:错误:关系“任务”的列“ user_group_ids”不存在

Query generated: 查询生成:

SQL (0.6ms) UPDATE "tasks" SET "user_group_ids" = 4, "release_date" = '2017-04-27 07:40:26.525357' WHERE "tasks"."deleted_at" IS NULL AND "tasks"."id" = 47394 SQL(0.6ms)UPDATE“任务” SET“ user_group_ids” = 4,“ release_date” ='2017-04-27 07:40:26.525357'WHERE“任务”。“ deleted_at”是NULL和“任务”。“ id” = 47394

Please let me know how to do it with update_all 请让我知道如何使用update_all

Why did you have to create the UserGroup model? 为什么必须创建UserGroup模型? That's not the way we use a habtm relationship. 那不是我们使用habtm关系的方式。

And your model Task , in the middle of it all, kind of confused me. 而您的模型Task ,在所有这些中间,让我感到困惑。 What do you need to do? 你需要做什么? I suspect that you don't have a habtm relationship in Task . 我怀疑你没有habtm的关系Task

For the error you're getting, it's totally understandable. 对于您遇到的错误,这是完全可以理解的。 You do not have an attribute (column) called user_group_ids in the tasks table. 您在tasks表中没有名为user_group_ids的属性(列)。 And also, for a habtm relationship, this attribute user_group_ids seems misspelled to me. 而且,对于habtm关系,此属性user_group_ids在我看来似乎拼写错误。

Anyway, for a habtm relationship, if your User has many Groups and a Group can have many Users, you're in the right path, however for Ruby on Rails there's two ways you can accomplish that. 无论如何,对于habtm关系,如果您的用户有多个组,而一个组可以有多个用户,那么您就走在正确的道路上,但是对于Ruby on Rails,有两种方法可以实现。

  1. If you don't need to manage other data (relationship attributes) in the relationship table: 如果您不需要管理关系表中的其他数据(关系属性):

    • Then you'll need only the table groups_users , in your case. 然后,您只需要表groups_users Rails will look for habtm relationship table in alphabetic order. Rails将按字母顺序查找habtm关系表。
  2. If your groups_users relationship holds any other data than model's reference ids, then it's better for you to use a has_many :through relationship. 如果您的groups_users关系包含模型参考ID以外的任何其他数据,那么最好使用has_many :through关系。

    • In this case your UserGroup (mind the singularity) table will hold the additional data you need in the relationship. 在这种情况下,您的UserGroup(请注意奇点)表将保存关系中所需的其他数据。 Then you declare as follows: 然后您声明如下:

    • User model will have declared: has_many :groups, through: :user_groups User模型将通过以下方式声明: has_many :groups, through: :user_groups

    • Group model will have declared: has_many :users, through: :user_groups Group模型将通过以下方式声明: has_many :users, through: :user_groups
    • UserGroup model: belongs_to :user and belongs_to :group . UserGroup型号: belongs_to :userbelongs_to :group Be careful not to index any of those as unique, database or application level. 注意不要将其中任何一个索引为唯一,数据库或应用程序级别。

For more details check http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association 有关更多详细信息,请访问http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association

Hope you get your results! 希望你能得到你的结果!

您的解决方案(不引起N + 1)是activerecord-import

You can't mass-assign the association using update_all . 您无法使用update_all批量分配关联。 update_all does a single UPDATE query but for association you actually need an INSERT query to insert the associated models. update_all执行一个UPDATE查询,但是对于关联,实际上需要一个INSERT查询来插入关联的模型。 You could use a gem like bulk_insert to insert all the join objects with one INSERT query https://github.com/jamis/bulk_insert 您可以使用bulk_insert类的gem通过一个INSERT查询https://github.com/jamis/bulk_insert插入所有bulk_insert对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM