在特定时间范围内按投票数对帖子进行排序

时间:2012-05-25 19:50:25

标签: ruby-on-rails ruby-on-rails-3 sorting date vote

我目前在我的应用程序中实现了一个投票系统,我在我的视图中使用此代码按照投票数对帖子进行排序:

  <%= render @posts.sort_by { |post| post.votes.count }.reverse %> 

我希望按照每个帖子的投票数进行排序,也不希望帖子比5天之前更好。如何同时按投票数和日期对帖子进行排序。

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)

luacassus是对的。最好将排序委托给数据库,原因至少有两个:

  1. 性能
  2. 您可以将更多查询方法链接到它上(例如,分页所必需的)。
  3. 计数器缓存可能是最好的主意,但对于复杂的查询,让我试一试。在你的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;的帖子#最“

并使用我在视图中的原始代码查看。

我知道这不是最好的方式,但我仍然是编码的新手,所以它是我弄清楚如何的最佳方式。