ActiveRecord_Relation对象的大小

时间:2017-09-04 21:59:12

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

我有以下查询:

User.joins(:posts).group('users.id').having('count(user_id) > 1')

返回的课程为User::ActiveRecord_Relation

如果我在其上调用.size,它会返回一个哈希值。如果我拨打.size.size,我会收到正确的尺寸。

这真的是我应该如何获得ActiveRecord_Relation的大小,或者其他方法是否正确?

2 个答案:

答案 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