开发者

ActiveRecord way of sorting a group before ordering

I have this active record query:

@reviews = Review.limit(30).group('user_id').order('created_at desc')
开发者_如何学JAVA

I'm using the group method to ensure I only display one review per user. The problem is that this review is not necessarily the last created review by that user.

I understand grouping happens before ordering so is it possible somehow to sort a group before calling order?


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


I have found many answers to this question but each requires raw sql, when you have simple query you can use it, for your input it will be something like this:

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"
)

but if query is more complicated and need more joins then you can use the almost good solution mentioned earlier, I am not sure if it is the best solution but it works for me:

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

edit: Yes, the last solution isn't right because it executes two queries to DB. I have accidently came back to this problem today and I have used the to_sql method (shipped with > Rails 3.0) along with first solution, for me its perfect - 1. still one query, 2. subquery can be as complicated as you wish and the code readability will remain same:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜