[英]Eager loading with has_many through
我有一个User
模型。
user
有许多integrations
。
一个integration
是加入一个profile
通过integration_profiles
其中包含一列data
。
我想急切加载所有用户的个人资料。
class Integration < ActiveRecord::Base
has_many :integration_profiles
has_many :profiles, through: :integration_profiles
end
class IntegrationProfile < ActiveRecord::Base
belongs_to :integration
belongs_to :profile
end
class Profile < ActiveRecord::Base
has_many :integration_profiles
has_many :integrations, through: :integration_profiles
end
我试过这个:
all = User.first.integrations.includes(:profiles)
但是当我做all.count
时候我
=> 2
但是,当我这样做
all = User.first.integrations.joins(:profiles)
all.count
=> the correct total
我应该使用包含还是加入? 我一直使用包括所以不确定为什么这不起作用
当你这样做
all = User.first.integrations.joins(:profiles)
all.count
将为第一个User
计算集成记录,并在profiles
上使用内部联接查询。
而当你这样做
all = User.first.integrations.includes(:profiles)
all.count
再次,你得到集合计数BUT没有连接查询与配置文件,因为配置文件由于includes
急切加载单独的查询
您似乎只想要与给定user
关联的profiles
计数。 实现此目的的最佳方法是在User
和Profile
模型之间创建关联
User ==> has_many :profiles, through: :integration
完成后,您可以直接访问User.first.profiles.count
以获取特定用户的所有关联配置文件的计数。
另一个选项是(如果你不想使用上面的选项)循环遍历所有integrations
并总结每个集成的所有profiles.count
。
选择最适合您需求的选项。
查询1
all = User.first.integrations.includes(:profiles)
all.count
返回集成计数而不是配置文件。 配置文件急切加载。
如果你想知道配置文件的数量,那么它需要以这种方式完成。
ar = [ ]
all.each do |a|
ar << a.profiles.count
end
运行查询2时, ar.reduce(:+)
会给你相同的计数。
查询2
all = User.first.integrations.joins(:profiles)
all.count
在查询2的情况下,它返回integrartion_profiles表中的集成。
Select users from users limit 1;
Select integrations from integrations INNER JOIN integration_profiles on integration_profiles.integration_id = integrations.id where integrations.user_id = 'id of user'
要了解更多信息,请在查询1和查询2上调用.to_sql。
如果您想进行预先加载,那么使用包含是首选选项。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.