包括ActiveRecord查询中相关数据的计算

时间:2010-03-01 00:02:18

标签: ruby-on-rails activerecord

假设我有一些模型:UserPostVote。用户有很多帖子,帖子有很多票。投票可以是投票或投票(存储为布尔值)。我正在考虑的是进行这类查询的最佳方式:

  1. 所有用户,以及他们收到的总票数。
  2. 所有用户以及获得最多投票的帖子。
  3. 所有用户,以及他们收到的总票数(上下)。
  4. 我可以通过三种方式来提高效率:

    1. 使用循环计算控制器中的投票计数。这可能会做很多我不需要的额外查询和查询数据,比如每个帖子和每个投票记录。例如(第三个查询):

      @users = User.all
      @vote_count = @users.posts.votes.count # retrieves every post and vote, which I don't need
      
    2. 将投票计数存储为用户模型中的字段,并在投票时使用回调更新这些计数。这会使查询更简单,但我希望模型更加松散耦合,并且每当我需要相关模型上的某种数据时,用户模型的模式就不会增长。

    3. 使用某种查询,它将通过SQL执行这些类型的计算,而不是查找比我需要的更多数据。这似乎是最好的选择,但我不知道如何处理它。有什么建议/例子吗?谢谢!

1 个答案:

答案 0 :(得分:1)

使用vote_fu plugin。它支持以下方法:

user.vote_count       # all votes
user.vote_count(true) # votes for
user.vote_count(false) # votes against
posts.votes_count   # all vote count
posts.votes_for     # votes for
posts.votes_against # votes against
posts.votes_total   # votes total

如果您不想使用该插件,那么我将按照以下方式处理您的方案:

我假设模特之间存在以下关系。

class User < ActiveRecord::Base
  has_many :posts
  has_many :votes, :through => :posts
end

class Post < ActiveRecord::Base
  belongs_to :user
  has_many :votes
end

class Vote < ActiveRecord::Base
  belongs_to :post
end

1.1)计算所有用户投票的所有投票

Vote.count  # all
Vote.count(:conditions => {:vote => true}) # all for
Vote.count(:conditions => {:vote => false}) # all against

1.2)查找用户的投票

user.votes.count # all
user.votes.count(:conditions => {:vote => true}) # all for
user.votes.count(:conditions => {:vote => false}) # all against

2.1)投票率最高的用户

# You can add the limit clause to restrict the rows
User.find(:all, :select => "users.*, count(votes.id) AS count", 
                :joins => [:posts, :votes],  
                :conditions => [" votes.vote = ? ", true],
                :group => "votes.id", :order => "count DESC")

2.2)最多投票的帖子

# You can add the limit clause to restrict the rows
Post.find(:all, :select => "posts.*, count(votes.id) AS count", 
                :joins => [:votes],  
                :conditions => [" votes.vote = ? ", true],
                :group => "votes.id", :order => "count DESC")

3.1)对于用户总票数   参见1.2.1