我如何渴望加载并加入多态条件?

时间:2018-07-04 03:50:39

标签: ruby-on-rails activerecord ruby-on-rails-5 polymorphic-associations

这是我的模特:

Course

我了解您可以通过以下方式解决您的N + 1问题:

String

现在,我只想在某种条件下加入权限。例如,如果它们不属于一组ID,那么我希望它可以工作,但是会引发错误。

name

进一步研究它,我发现以下内容可以按照我想要的方式工作,但它不能解决N + 1问题。

class Team < ApplicationRecord
  has_many :team_permissions
end

class TeamPermission < ApplicationRecord
  belongs_to :team
  belongs_to :permissible, polymorphic: true
end

class User < ApplicationRecord
  has_many :team_permissions, as: :permissible
end

如何为条件中的Team.includes(team_permissions: :permissible) 紧急加载?

1 个答案:

答案 0 :(得分:2)

不幸的是,Active Record不够聪明(老实说,也没有足够的信任度),无法确定它需要加入第一个表来应用您的条件,但是没有第二个表。

您应该能够通过稍微明确一些来帮助解决问题:

Team.
  includes(:team_permissions).   # or eager_load(:team_permissions).
  preload(team_permissions: :permissible).
  where.not(team_permissions: { id: team_permission_ids }

在没有条件引用includes表时,默认行为是使用preload,它通过执行单个附加查询来处理N + 1,并且与多态关联兼容。但是,当找到这样的条件时,includes all 会转换为eager_load,这会在主查询中进行LEFT JOIN操作(因此不兼容:无法编写一个查询,该查询将连接到我们甚至不知道的表。

上面,我已经分离出我们绝对希望通过preload加载的零件,因此它应该做正确的事情。