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

Rails如何从Post集合中高效获取唯一关联User(作者)?

Optimal Way to Get Unique Authors from a Collection of Posts

Great question! Let's walk through your current approaches first, then dive into a more efficient solution.

Breaking down your existing methods:

  • @posts.map(&:author).uniq(&:id): This is the least performant option by far. It triggers an N+1 query (one to load posts, then one per post to load its author), and handles deduplication in Ruby. For large post collections, this wastes both database resources and Ruby processing power—something the database is way better at handling.

  • User.where(id: @posts.pluck(:author_id)): This is a solid improvement! pluck(:author_id) grabs just the author IDs in one query, then User.where(...) fetches matching users in another. The database automatically deduplicates users even if pluck returns repeated IDs, so you get unique authors. That said, we can trim this to a single database query for even better speed.

The Most Efficient Solution

Instead of two separate database calls, we can combine the post filter and user lookup into one optimized query using ActiveRecord joins:

# Make sure your models have the right associations:
# Post model: belongs_to :author, class_name: 'User'
# User model: has_many :posts, foreign_key: :author_id
User.joins(:posts).merge(@posts).distinct

If you prefer being explicit with post IDs, this works too:

User.joins(:posts).where(posts: { id: @posts.ids }).distinct

Why this is better:

  1. Single database query: Eliminates the extra round trip from the pluck step, cutting down on database overhead.
  2. Database-level deduplication: The DISTINCT clause tells the database to return only unique users, so we don't waste Ruby cycles processing duplicates.
  3. Optimized relational logic: Databases are built for this kind of cross-table filtering and deduplication—they'll handle it faster than Ruby ever could.

Quick Tip

If @posts is an ActiveRecord Relation (not an already-loaded array of posts), merge(@posts) will seamlessly combine your post query conditions into the user query, keeping everything as one streamlined SQL statement.


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:32:12