代码之家  ›  专栏  ›  技术社区  ›  Fellow Stranger

ActiveRecord_关系对象的大小

  •  3
  • Fellow Stranger  · 技术社区  · 7 年前

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

    返回的类是 User::ActiveRecord_Relation

    如果我打电话 .size 它返回一个散列。如果我打电话 .size.size 我得到了正确的尺寸返回。

    这真的是我应该如何获得ActiveRecord\u关系的大小,还是正确的方法?

    2 回复  |  直到 7 年前
        1
  •  6
  •   EJAg    7 年前

    重要的是要理解为什么你打电话时会得到一个哈希值 #size 在这里

    将执行 SELECT COUNT(*) 查询关联是否尚未加载。这相当于呼叫 #count

    #大小 不会执行任何其他查询,但将获取关联的长度。在本例中,是散列的长度。在控制台中尝试以下操作:

    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
    

    所以依赖链接不是一个好主意 #大小 除非您确定在此之前不会加载关联。相反,使用 #length

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

    #长度 不执行额外的查询,并且总是将整个关联加载到内存中,因此速度有点慢,而且更饿。但在实践中,这通常不是一个问题,除非你加载了大量的记录。

    顺便说一句,如果你只想找到拥有多个帖子的用户数量,那么就不需要 #join :

    Post.group('user_id').having('count(user_id) > 1').length
    
        2
  •  1
  •   iskvmk    7 年前

    你打过电话 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