ActiveRecord在订购之前对组进行排序的方式

时间:2011-03-17 22:36:41

标签: ruby-on-rails activerecord

我有这个有效的记录查询:

@reviews = Review.limit(30).group('user_id').order('created_at desc')

我正在使用群组方法来确保每个用户只显示一次审核。 问题是该审核不一定是该用户最后创建的审核。

我理解分组是在订购之前发生的,所以在调用订单之前是否有可能以某种方式对一个组进行排序?

2 个答案:

答案 0 :(得分:0)

ids = Review.group(:user_id).maximum(:created_at).keys
@reviews = Review.limit(30).where(:id => ids).order(:created_at)

答案 1 :(得分:0)

我找到了很多这个问题的答案,但每个都需要原始的sql,当你有简单的查询就可以使用它时,对于你的输入,它将是这样的:

Review.find_by_sql(
 "SELECT * FROM (
 SELECT * FROM reviews
 ORDER BY reviews.created_at DESC ) as my_table
 group by my_table.user_id
 LIMIT 30"
)

但是如果查询更复杂并且需要更多连接,那么你可以使用前面提到的几乎所有的解决方案,我不确定它是否是最好的解决方案,但它对我有用:

ids = Review.order('created_at DESC').pluck(:id)
@reviews = Review.where(id: ids).group(:user_id).limit(30)

编辑:是的,最后一个解决方案并不正确,因为它会对DB执行两次查询。我今天意外地回到了这个问题,并且我使用了to_sql方法(与> Rails 3.0一起提供)以及第一个解决方案,对我来说它是完美的 - 1.仍然是一个查询,2。子查询可以是如你所愿复杂,代码可读性将保持不变:

Review.find_by_sql(
     "SELECT * FROM (
     #{ Review.order(:created_at).to_sql }
     ) as my_table
     group by my_table.user_id
     LIMIT 30"
    )