简单的ActiveRecord问题

时间:2011-06-28 17:39:40

标签: ruby-on-rails activerecord will-paginate

我设置了一个数据库模型,使得帖子有很多票,用户有很多票,帖子属于用户和帖子。我正在使用will paginate,我正在尝试创建一个过滤器,以便用户可以按帖子的日期或投票数对帖子进行排序。日期选项很简单,如下所示:

@posts = Post.paginate :order => "date DESC"

但是,我无法确定如何进行投票的订购。如果这是SQL,我只需在GROUP BY列上使用user_id以及count函数,然后我将结果与posts表一起使用。

使用ActiveRecord的正确方法是什么?

2 个答案:

答案 0 :(得分:2)

1)使用counter cache mechanism将投票计数存储在Post模型中。

# add a column called votes_count
class Post
  has_many :votes
end

class Vote
  belongs_to :post, :counter_cache => true
end

现在,您可以按照投票计数对Post模型进行排序,如下所示:

Post.order(:votes_count)

2)使用group by。

Post.select("posts.*, COUNT(votes.post_id) votes_count").
  join(:votes).group("votes.post_id").order(:votes_count)

如果您想在结果集中包含没有投票的帖子,那么:

Post.select("posts.*, COUNT(votes.post_id) votes_count").
  join("LEFT OUTER JOIN votes ON votes.post_id=posts.id").
  group("votes.post_id").order(:votes_count)

我更喜欢方法1,因为它有效且投票计算的成本是预先加载的(即在投票期间)。

答案 1 :(得分:1)

使用选项将所有正常的SQL内容作为查询的一部分。

@posts = Post.paginate :order => "date DESC", :join => " inner join votes on post.id..." , :group => " votes.user_id"

http://apidock.com/rails/ActiveRecord/Base/find/class

所以我对你的模型了解不多,但你似乎对SQL有些了解

命名范围:您基本上只是将查询放入类方法:

named_scope :index , :order => 'date DESC', :join => .....

但他们可以参数

named_scope :blah, {|param| #base query on param }

对你而言,特别是如果你更熟悉SQL,你可以编写自己的查询,

@posts = Post.find_by_sql( <<-SQL ) 
  SELECT posts.*
  ....
SQL