Ruby-on-Rails:如何从数据库表的有限子集中提取最新的条目
想象一下像模特这样的用户谁有很多朋友,每个人都有很多评论,我试图向用户显示他的朋友最新的100条评论。
是否有可能在单个SQL查询中提取最新的100个,或者我将不得不使用Ruby应用程序逻辑来解析更大的列表或进行多个查询?
我看到了两种解决方法:
- 从User.find开始,使用一些复杂的组合:join和:limit。 这种方法看起来很有希望,但不幸的是,它会让我回复用户而不是评论,一旦我得到回复,我会有很多模型占用内存(对于每个朋友和用户),许多不必要的字段被转移(一切对于用户,以及关于朋友的名称行的所有内容),我仍然需要以某种方式逐步收集并排序应用程序逻辑中的所有注释。
- 从评论开始并使用某种find_by_sql,但我似乎无法弄清楚我需要放入什么。我不知道你怎么能得到必要的信息来传递它来限制它只看朋友的评论。
编辑 :我很难让EmFi的解决方案工作,并且会欣赏任何人都可以提供的任何见解。
朋友是通过连接表的循环关联。
has_many :friendships has_many :friends, :through => :friendships, :conditions => "status = #{Friendship::FULL}"
这是我在相关部分得到的错误:
错误:列users.user_id不存在
: SELECT "comments".* FROM "comments" INNER JOIN "users" ON "comments".user_id = "users".id WHERE (("users".user_id = 1) AND ((status = 2)))
当我刚进入user.friends,它工作时,这是它执行的查询:
: SELECT "users".* FROM "users" INNER JOIN "friendships" ON "users".id = "friendships".friend_id WHERE (("friendships".user_id = 1) AND ((status = 2)))
所以它似乎正在破坏:通过在一个查询中有两个:through。
鉴于以下关系:
class User < ActiveRecord::Base has_many :friends has_many :comments has_many :friends_comments, :through => :friends, :source => :comments end
该语句将执行单个SQL语句。 关联实际上为您创建了命名范围,直到链的末尾才对其进行求值。
@user.friends_comments.find(:limit => 100, :order => 'created_at DESC')
如果这是一个常见查询,则可以将查找简化为其自己的范围。
class Comments < ActiveRecord::Base belongs_to :user #named_scope was renamed to scope in Rails 3.2. If you're working #if you're working in a previous version uncomment the following line. #named_scope :recent, :limit => 100, : order => 'created at DESC' scope :recent, :limit => 100, :order => 'created_at DESC' end
所以现在你可以这样做:
@user.friends_comments.recent
注意:用户上的朋友关联可能是通过连接表的循环关联,但这对此解决方案并不重要。 只要朋友是用户的工作协会,前面的工作就可以了。