2017-04-27 38 views
0

我有两个模型,它们之间的关联是has_and_belongs_to_many。 我需要重构代码,因为它会导致n + 1个查询。update_all方法不适用于关联记录

问题: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 

要求:

Assign Tasks to 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" of relation "tasks" does not exist

查询生成:

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

请让我知道如何与update_all

回答

0

做到这一点你为什么要创建用户组的模式?这不是我们使用habtm关系的方式。

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

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

无论如何,对于一个habtm关系,如果您的用户有很多组和一组可以有很多用户,你在正确的道路,但是,对于Ruby on Rails的出现是你能够做到这两个方面。

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

    • 然后,你只需要在表groups_users,你的情况。 Rails将按字母顺序查找habtm关系表。
  2. 如果您groups_users关系保持高于模型的参考ids中的任何其他数据,那么它是更好地为您使用has_many :through关系。

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

    • User模式将宣布:has_many :groups, through: :user_groups

    • Group模式将宣布:has_many :users, through: :user_groups
    • UserGroup型号:belongs_to :userbelongs_to :group。小心不要将这些索引编入索引,作为唯一的数据库或应用程序级别。

有关详情,请http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association

希望你得到你的结果!

+0

user_group表具有已添加的业务逻辑。由于用户可以属于多个组,并且组可以根据他们的权限同时进行访问。 –

+0

我可以通过关联添加'has_many'。我需要将任务分配给不同的user_groups的逻辑,但是之前写入的方式导致了“n + 1”查询。我需要解决这个问题。 –

+0

我可以看到,但问题是您的Task表中没有'user_group_ids'列。你可以解决写入迁移来添加该列,但我的感觉是,你有一个建模问题,目前还不可见 - 你的关系似乎很混乱。 – GPrimola