You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails中如何查询获取所有用户列表及各自的文章数量

问题根源

你写的查询用joins(:posts)默认生成INNER JOIN,只返回存在关联Post的用户,自然会把没发过文章的用户过滤掉。之前用include的方案是预加载全量关联数据,确实会把所有Post记录载入内存,资源浪费严重。

正确实现

用左外连接(LEFT OUTER JOIN)替代内连接即可,聚合计算直接在数据库层完成,不会加载全量Post数据,性能远高于预加载方案。

Rails 5+ 原生写法

Rails 5 内置了左连接方法left_joins(别名left_outer_joins),代码如下:

User.left_joins(:posts)
    .select('users.*, COUNT(posts.id) AS post_count')
    .group('users.id')

查询返回的每个User对象都会自带post_count属性,没有发布过文章的用户该属性值为0,完全覆盖全量用户的统计需求。

原理说明:

  • 左外连接会保留users表的所有记录,就算用户没有对应Post也不会被剔除
  • COUNT(posts.id)会自动忽略连接生成的NULL值,不会把无Post的用户统计为1或者报错
  • 最终查询结果只包含用户字段和聚合后的计数值,不会把所有Post记录载入内存,没有额外性能损耗

Rails 4及更低版本适配

老版本没有内置左连接语法,可以手动写SQL片段实现:

User.joins('LEFT OUTER JOIN posts ON posts.user_id = users.id')
    .select('users.*, COUNT(posts.id) AS post_count')
    .group('users.id')

踩坑提示

如果要统计符合特定条件的文章数(比如仅统计已发布、未删除的文章),不要直接在主查询的where条件里加Post的过滤规则,否则会把无匹配Post的用户过滤掉。这类场景要把过滤条件写到LEFT JOIN的ON子句里,或者通过带条件的关联来实现。


内容的提问来源于stack exchange,提问作者leonchik12

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 13:00:15