我有一个模型用户,它有很多帖子。要查询前 5 个用户,我会:
User.all :limit => 5
它返回一个很好的用户,但是当获取每个用户拥有的帖子数时,它会再次查询数据库:
a_user.posts.count
有没有办法可以避免此查询并通过第一个查询获得计数?我正在遍历用户,每次查询用户帖子的计数时都会阻塞。
我有一个模型用户,它有很多帖子。要查询前 5 个用户,我会:
User.all :limit => 5
它返回一个很好的用户,但是当获取每个用户拥有的帖子数时,它会再次查询数据库:
a_user.posts.count
有没有办法可以避免此查询并通过第一个查询获得计数?我正在遍历用户,每次查询用户帖子的计数时都会阻塞。
Rails 有一个内置方法,在声明 has_many 之类的关联时必须将其设置为 true,而且您必须向数据库添加一列。
counter_cache: true
声明has_many
关联时设置
添加#{table_name}_count
到数据库,它会自动增加和减少,所以您可以在查询前五个用户时直接选择该列。
更多信息:
http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
您正在寻找 rails eager loading 的方法#includes
,它仍然会创建两个查询(但不是 6,如果您这样做User.all, :limit=>5
,然后user.posts
在每个查询上),但会在一个查询中加载帖子:
User.includes(:posts).limit(5)
这应该创建SQL:
SELECT * FROM users LIMIT 5
SELECT posts.* FROM posts
WHERE (posts.user_id IN (1,2,3,4,5)) # Numbers are found ID
您可以从Active Record 查询指南中找到此信息