我目前在我的应用程序中实现了一个投票系统,我在我的视图中使用此代码按照投票数对帖子进行排序:
<%= render @posts.sort_by { |post| post.votes.count }.reverse %>
我希望按照每个帖子的投票数进行排序,也不希望帖子比5天之前更好。如何同时按投票数和日期对帖子进行排序。
答案 0 :(得分:2)
这是错误的。您应该在数据库端执行所有排序操作。 对于此示例,请考虑使用Arel创建复杂查询或考虑创建计数器缓存列。
答案 1 :(得分:1)
您可以在帖子模型中添加范围,例如:
scope :five_days_ago, lambda { where("created_at >= :date", :date => 5.days.ago) }
然后只需将渲染方法调整为以下内容:
<%= render @posts.five_days_ago.sort_by { |post| post.votes.count }.reverse %>
这假设您要保留正在使用的结构。显然,正如其他人所建议的那样,在数据库中完成这一切是最好的行动方式。
答案 2 :(得分:1)
计数器缓存可能是最好的主意,但对于复杂的查询,让我试一试。在你的Post模型中:
class << self
def votes_descending
select('posts.*, count(votes.id) as vote_count').joins('LEFT OUTER JOIN votes on votes.post_id = posts.id').group_by('posts.id').order('votes_count desc')
end
def since(date)
where('created_at >= ?', date)
end
end
因此...
@posts = Post.votes_descending.since(5.days.ago)
答案 3 :(得分:0)
确实让db进行排序会更好。我会做类似
的事情class Post < ActiveRecord::Base
default_scope :order => 'created_at DESC'
end
然后你总会对你的帖子进行排序,如果我没有弄错,最后一个应该是你得到的第一个,所以用你的'反向'来代替。然后你可以使用上面发布的范围只获得5天的帖子。还要检查db中的created_at列是否有索引。您可以使用
执行此操作SHOW INDEX FROM posts
db会比ruby快得多。
答案 4 :(得分:0)
我想出了另一种方法,虽然我感谢你的帮助,但它可能不是最干净的方式,但我做了
def most
range = "created_at #{(7.days.ago.utc...Time.now.utc).to_s(:db)}"
@posts = Post.all(:conditions => range)
@title = "All Posts"
@vote = Vote.new(params[:vote])
respond_to do |format|
format.html
format.json { render :json => @users }
end
end
为我的控制器
创建了/ most的路线:to =&gt;的帖子#最“
并使用我在视图中的原始代码查看。
我知道这不是最好的方式,但我仍然是编码的新手,所以它是我弄清楚如何的最佳方式。