我设置了一个数据库模型,使得帖子有很多票,用户有很多票,帖子属于用户和帖子。我正在使用will paginate,我正在尝试创建一个过滤器,以便用户可以按帖子的日期或投票数对帖子进行排序。日期选项很简单,如下所示:
@posts = Post.paginate :order => "date DESC"
但是,我无法确定如何进行投票的订购。如果这是SQL,我只需在GROUP BY
列上使用user_id
以及count
函数,然后我将结果与posts表一起使用。
使用ActiveRecord的正确方法是什么?
答案 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