我有以下查询:
User.joins(:posts).group('users.id').having('count(user_id) > 1')
返回的课程为User::ActiveRecord_Relation
。
如果我在其上调用.size
,它会返回一个哈希值。如果我拨打.size.size
,我会收到正确的尺寸。
这真的是我应该如何获得ActiveRecord_Relation的大小,或者其他方法是否正确?
答案 0 :(得分:1)
您调用了group
方法,这就是为第一个.size
调用返回哈希的原因。
假设您在第一次调用size
时有以下哈希:
hash = {106=>1, 171=>1, 79=>1, 66=>1, 160=>3, 73=>1, 182=>1, 165=>1, 97=>7, 116=>1}
然后你需要对该散列中的所有值求和:
hash.values.reduce(:+)
=> 18
答案 1 :(得分:1)
了解为什么在此处致电#size
时获得哈希值非常重要。
#size
将执行SELECT COUNT(*)
查询。这相当于调用#count
。所以你得到一个哈希。
但是如果某种关联已经被加载到内存中,#size
不会执行任何其他查询,但会获得关联的长度。在这种情况下,哈希的长度。在控制台中尝试以下操作:
query = User.joins(:posts).group('users.id').having('count(user_id) > 1'); #don't load the association
query.size # => hash
query.size # => length of the previous hash
因此,除非您确定在此之前不会加载关联,否则依赖链接#size
并不是一个好主意。相反,请使用#length
:
User.joins(:posts).group('users.id').having('count(user_id) > 1').length # => integer
#length
不会执行其他查询,并且会始终将整个关联加载到内存中,因此它会慢一点并且更加饥饿。但在实践中,除非您正在加载大量记录,否则通常不会出现问题。
顺便说一句,如果你想要的只是查找有多个帖子的用户数量,那就不需要#join
:
Post.group('user_id').having('count(user_id) > 1').length