update_all方法不适用于关联记录

时间:2017-04-27 07:43:16

标签: ruby-on-rails postgresql ruby-on-rails-4 update-all

我有两个模型,它们之间的关联是has_and_belongs_to_many。 我需要重构代码,因为它会导致n + 1个查询。

问题:n + 1次查询

1。任务

    class Task < ActiveRecord::Base
      has_and_belongs_to_many :user_groups
    end

2。用户组

    class UserGroup < ActiveRecord::Base
      has_and_belongs_to_many :tasks
    end

要求:

  

将任务分配给user_groups

以前的控制器代码:

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

我的尝试:

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

错误:

  

ActiveRecord :: StatementInvalid(PG :: UndefinedColumn:ERROR:column   关系“任务”的“user_group_ids”不存在

查询已生成:

  

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和“tasks”。“id”= 47394

请通过update_all

告诉我如何操作

3 个答案:

答案 0 :(得分:0)

为什么必须创建UserGroup模型?这不是我们使用habtm关系的方式。

你的模型Task,在这一切的中间,有点困惑我。你需要做什么?我怀疑您在habtm中没有Task关系。

对于你得到的错误,这完全可以理解。您在user_group_ids表中没有名为tasks的属性(列)。此外,对于habtm关系,此属性user_group_ids似乎拼写错误。

无论如何,对于habtm关系,如果你的用户有很多组,而一个组可以拥有很多用户,那么你就是正确的道路,但是对于Ruby on Rails,有两种方法可以实现这一点。 / p>

  1. 如果您不需要管理关系表中的其他数据(关系属性):

    • 那么在您的情况下,您只需要表groups_users。 Rails将按字母顺序查找habtm关系表。
  2. 如果您的groups_users关系包含除模型参考ID之外的任何其他数据,那么您最好使用has_many :through关系。

    • 在这种情况下,您的UserGroup(介意奇点)表将保存关系中所需的其他数据。然后你声明如下:

    • User模型已声明:has_many :groups, through: :user_groups

    • Group模型已声明:has_many :users, through: :user_groups
    • UserGroup型号:belongs_to :userbelongs_to :group。注意不要将其中任何一个索引为唯一,数据库或应用程序级别。
  3. 有关详细信息,请查看http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association

    希望你得到你的结果!

答案 1 :(得分:0)

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

答案 2 :(得分:0)

您无法使用update_all大规模分配关联。 update_all仅执行一个UPDATE查询,但实际上,要进行关联,您需要一个INSERT查询来插入关联的模型。您可以使用bulk_insert之类的gem通过一个INSERT查询https://github.com/jamis/bulk_insert

插入所有联接对象。