高效地遍历所有用户并返回3个相关项[SQL][Rails]

高效地遍历所有用户并返回3个相关项[SQL][Rails],sql,ruby-on-rails,eager-loading,Sql,Ruby On Rails,Eager Loading,我在运行rails 4。我们有一个用户模型有许多帖子。 我想创建一个“feed”,显示站点中每个用户最多三篇帖子 我能得到的最接近的东西是 # GET /users # GET /users.json def index users = User.includes(:posts) users.each do |user| @feed_items << user.posts.limit(3) end @comment = Com

我在运行rails 4。我们有一个
用户
模型
有许多
帖子
。 我想创建一个“feed”,显示站点中每个用户最多三篇帖子

我能得到的最接近的东西是

  # GET /users
  # GET /users.json
  def index
    users = User.includes(:posts)
    users.each do |user|
       @feed_items << user.posts.limit(3)
    end
    @comment = Comment.new
  end
#获取/用户
#GET/users.json
def索引
users=User.includes(:posts)
用户。每个do |用户|

@feed_itemsincludes
已在单个查询中读取每个用户的所有帖子。因此,您应该能够在ruby中获得每种方法的前三种,而无需再次查询数据库

users = User.includes(:posts)
@feed_items = []
users.each do |user|
   @feed_items += user.posts.first(3)
end

这形成了一个长长的帖子列表。如果您想要每个用户列表的列表,请使用
那里没有任何东西可以执行
n+1
查询。什么让你想到一个是必需的?什么是“n+1”查询?我已经澄清了这个问题@Gene@HarryMoreno看到变化了吗?哈利莫雷诺,我可以测试一下。很好。希望这是有帮助的。另一方面,我认为每个用户在未来会有更多的帖子。我正在考虑创建一个单独的索引,用户可以在其中选择他们的“前三名”。这样我就不会花那么多内存了。我该怎么做?另一张表?我参加了一个在线比赛,所有参赛作品都被永久保存,我经常需要检索一份按最佳参赛作品排名前N名的球队名单。这与您的问题类似。每个队只需要许多参赛作品中最好的。最后,我保存了一个“最佳”表格,其中保存了每个团队最佳参赛作品的外键。这是我能找到的唯一方法,让排名前N的团队查询足够高效。您的问题与此类似,但每个用户(在我的情况下是团队)都需要排名前3位。注意,您可能必须使用Rails锁定,以使两个表中的相关更新看起来是原子的。
User Load (4.4ms)  SELECT "users".* FROM "users" 
Post Load (2.4ms)  SELECT "posts".* FROM "posts" WHERE "posts"."user_id" IN (4, 5, 6, 7, 8, 9, 10, 11, 12, 13)
irb(main):037:0> @feed_items.map &:subject
=> ["User 0's Post 1", "User 0's Post 2", "User 0's Post 3", "User 1's Post 1", 
"User 1's Post 2", "User 1's Post 3", "User 2's Post 1", "User 2's Post 2", 
"User 2's Post 3", "User 3's Post 1", "User 3's Post 2", "User 3's Post 3", 
"User 4's Post 1", "User 4's Post 2", "User 4's Post 3", "User 5's Post 1", 
"User 5's Post 2", "User 5's Post 3", "User 6's Post 1", "User 6's Post 2", 
"User 6's Post 3", "User 7's Post 1", "User 7's Post 2", "User 7's Post 3", 
"User 8's Post 1", "User 8's Post 2", "User 8's Post 3", "User 9's Post 1", 
"User 9's Post 2", "User 9's Post 3"]