当前位置:  开发笔记 > 后端 > 正文

Rails:独特用户的三条最新评论

如何解决《Rails:独特用户的三条最新评论》经验,为你挑选了1个好方法。

我将在命名范围中放入什么:by_unique_users以便我可以执行Comment.recent.by_unique_users.limit(3),并且每个用户只能获得一条评论?

class User
  has_many :comments
end

class Comment
  belongs_to :user
  named_scope :recent, :order => 'comments.created_at DESC'
  named_scope :limit, lambda { |limit| {:limit => limit}}
  named_scope :by_unique_users
end

在sqlite named_scope:by_unique_user,:group =>"user_id"工作,

但是它会在postgres上出现问题,postgres部署在生产PGError:ERROR:列"comments.id"必须出现在GROUP BY子句中或用于聚合函数



1> Max Chernyak..:

Postgres与MySQL和SQLite的不同之处在于它的处理方式GROUP BY.从本质上讲,它非常严格.让我们说你有.

id name
1  foo
2  bar
2  baz

那你就是在做GROUP BY id.MySQL假设您只想丢弃除名字之外的所有名称.所以它会产生.

id name
1  foo
2  bar

但是,在这种情况下,Postgres不会猜测分组方法.它需要有关如何对其他列进行分组的特定说明.它为此目的提供了所谓的聚合函数,在这种情况下,您正在寻找一个首先采用的函数.我找不到这样做的功能,但也许min()或者max()可以作为一个功能.在这种情况下,您需要使用:select => 'min(comments.id), min(comments.some_other_column)',除了user_id之外,您应该为每个列执行此操作.然后你可以使用:group =>'user_id'没有问题.

顺便说一句,min()并且max()接受字符串,不只是数字,所以他们应该对任何列工作.如果你想真正采取第一个,然后谷歌"postgres聚合首先"找到一些实现,或使用postgres数组.虽然这些会破坏与mysql和sqlite的兼容性.

更新

另一方面,如果获取最近的评论并不是太昂贵,那么让ruby处理独特的用户部分.

unique_comments = []
Comment.recent.each do |comment|
  unless unique_comments.find{|c| c.user_id == comment.user_id}
    unique_comments << comment
  end
  break if unique_comments.size > 2
end

现在,您最多有3条来自不同用户的评论.

推荐阅读
牛尾巴2010
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有