我有一个Work
带有video_id
,auser_id
和其他一些简单字段的模型。我需要在页面上显示最后12幅作品,但每位用户只需花1幅。目前,我正在尝试这样做:
def self.latest_works_one_per_user(video_id=nil)
scope = self.includes(:user, :video)
scope = video_id ? scope.where(video_id: video_id) : scope.where.not(video_id: nil)
scope = scope.order(created_at: :desc)
user_ids = works = []
scope.each do |work|
next if user_ids.include? work.user_id
user_ids << work.user_id
works << work
break if works.size == 12
end
works
end
但我敢肯定,这样做的方式会更优雅,更快捷,尤其是当作品数量增加时。
这是一种对任何SQL数据库都可以进行最小调整的解决方案。人们是否认为它很优雅取决于您对SQL的喜欢程度。
def self.latest_works_one_per_user(video_id=nil)
scope = includes(:user, :video)
scope = video_id ? scope.where(video_id: video_id) : scope.where.not(video_id: nil)
scope.
joins("join (select user_id, max(created_at) created_at
from works group by created at) most_recent
on works.user_id = most_recent.user_id and
works.created_at = most_recent.created_at").
order(created_at: :desc).limit(12)
end
但是,仅当user_id和created_at的组合是唯一的时才有效。如果该组合不是唯一的,您将获得超过12行。
可以在MySQL中更简单地完成。MySQL解决方案在Postgres中不起作用,我不确定在Postgres中有更好的解决方案,尽管我敢肯定有一个解决方案。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句