(rails) 按网站上的点赞数排序
Posted
技术标签:
【中文标题】(rails) 按网站上的点赞数排序【英文标题】:(rails) Order by Number of Likes on a Website 【发布时间】:2011-05-30 22:31:44 【问题描述】:我有一个模型叫做网站 has_many :likes
,当然还有另一个模型叫做喜欢 belongs_to :website
。我想获取所有网站的数组,但按网站拥有的点赞数对它们进行排序。
有用的信息:
我已经设置好了,所以@website.likes
将返回来自@website
的喜欢。 (@website.likes.count
是一个网站的点赞数)
我想获取所有网站的数组,但按网站的点赞数排序。
【问题讨论】:
sort
SQL IIRC 不这样做
如果@popularwebsites 中的站点数量很少,这可能是可以接受的。但是,如果您首先将所有网站拉入该数组,然后动态进行排序,它将变得昂贵且快速。此外,由于 x.likes.count 必须进行数据库查询,因此会遇到称为 N+1 查询的问题。
【参考方案1】:
正如其他人所发布的,您可以加入likes
,然后按数量排序。性能可能有点不确定,具体取决于索引等。根据您运行的是 Rails 2 还是 Rails 3,您的语法会略有不同。
另一种方法是在websites
上维护一个非规范化的likes_count
列,该列在保存Like
模型对象时更新。
那么你只需要在Website
上查询并指定likes_count
降序排列(并且很容易被索引)。
为此,请在websites
上创建一个likes_count
整数列,并在Likes
模型中的belongs_to
声明上指定:counter_cache
选项。例如:
class Likes
belongs_to :website, :counter_cache => true
end
查看http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html 了解更多信息
【讨论】:
快速简单!谢谢! (我认为其他人的反应也有效!) 很酷的解决方案!不利的一面是,例如,如果您从 db 控制台中删除了一个赞,那么该删除将不会反映在 likes_count 上。在这种情况下不是投标交易,而是需要注意的事项。 @randomguy 是正确的。这种非规范化技术依赖于通过 Ruby 创建/销毁Like
对象,并让 ActiveRecord
中的回调来处理内务。如果您在应用程序代码之外执行此操作,那么您需要自己进行内务处理,否则您的非规范化数据将进入无效状态。【参考方案2】:
这个查询应该给你你需要的东西:
all(:select => 'websites.*, count(*) as count',
:joins => :likes,
:group => :websites,
:order => 'count DESC')
【讨论】:
它不会返回没有任何赞的网站,因为内部连接会从结果集中删除所有没有赞的网站。【参考方案3】:类似的东西:
SELECT Websites.*, COUNT(Like.ID) AS Liked
FROM websites
LEFT OUTER JOIN Like ON websites.ID = Like.website_id
GROUP BY Like.website_id ORDER BY Liked DESC
【讨论】:
以上是关于(rails) 按网站上的点赞数排序的主要内容,如果未能解决你的问题,请参考以下文章