简单的 ActiveRecord 问题

发布于 2024-11-17 19:58:05 字数 351 浏览 5 评论 0原文

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

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

但是,我不太清楚如何对投票进行排序。如果这是 SQL,我只需在投票 user_id 列上使用 GROUP BY 以及 count 函数,然后加入结果与帖子表。

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

I have a database model set up such that a post has many votes, a user has many votes and a post belongs to both a user and a post. I'm using will paginate and I'm trying to create a filter such that the user can sort a post by either the date or the number of votes a post has. The date option is simple and looks like this:

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

However, I can't quite figure how to do the ordering for the votes. If this were SQL, I would simply use GROUP BY on the votes user_id column, along with the count function and then I would join the result with the posts table.

What's the correct way to do with with ActiveRecord?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浅笑依然 2024-11-24 19:58:05

1) 使用计数器缓存机制将投票计数存储在发布模型。

# 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) Use the counter cache mechanism to store the vote count in Post model.

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

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

Now you can sort the Post model by vote count as follows:

Post.order(:votes_count)

2) Use group by.

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

If you want to include the posts without votes in the result-set then:

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)

I prefer approach 1 as it is efficient and the cost of vote count calculation is front loaded (i.e. during vote casting).

等风也等你 2024-11-24 19:58:05

只需将所有正常的 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

Just do all the normal SQL stuff as part of the query with options.

@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

So I don't know much about your models, but you seem to know somethings about SQL so

named scopes: you basically just put the query into a class method:

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

but they can take parameters

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

for you, esp if you are more familiar with SQL you can write your own query,

@posts = Post.find_by_sql( <<-SQL ) 
  SELECT posts.*
  ....
SQL
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文