如何在模型中计算条件和?

时间:2010-09-23 07:47:09

标签: ruby-on-rails sum rails-activerecord

说我想在Rails中喜欢这个:

class Proposal < ActiveRecord::Base
    def interest_level
        self.yes_votes.count - self.no_votes.count
    end

  private
    def yes_votes
        self.votes.where(:vote => true)
    end

    def no_votes
        self.votes.where(:vote => false)
    end
end
  1. 上面的代码中我基本做错了什么? (我意识到它可能在很多方面都很糟糕。)
  2. 从Rails的角度来看,正确的方法是什么?
  3. 从数据库的角度来看,我应该注意哪些注意事项? (例如,即使像上面的这样的代码可能,我也猜测它在DB方面会过分。但我自然不太确定。)

3 个答案:

答案 0 :(得分:2)

class Proposal&lt;的ActiveRecord ::基

def interest_level
    self.votes.sum('votes', :conditions => {:votes = true}) - self.votes.sum('votes', :conditions => {:votes = false})
end

感谢, Anubhaw

答案 1 :(得分:2)

考虑到数据库加载,我建议实现自定义计数器缓存。我会这样做:

class Vote < ActiveRecord::Base

    def after_create
      self.update_counter_cache
    end

    def after_destroy
      self.update_counter_cache
    end

    def update_counter_cache
      self.proposal.yes_votes_count = self.proposal.votes.where(:vote=>true)
      self.proposal.no_votes_count = self.proposal.votes.where(:vote=>false)
      self.propsal.save
    end
end

请注意,您必须在Proposal模型中添加两​​列。

add_columns_migration.rb

add_column :proposals, :yes_votes_count, :integer
add_column :proposals, :no_votes_count, :integer

答案 2 :(得分:1)

我真的没有看到你的代码有任何明显的错误。虽然有很多方法可以完成你似乎想要做的事情,但是你的方法似乎应该可以正常工作(尽管我对Arel的经验有限)。

另一种方法可能只是更改interest_level方法:

def interest_level
    self.votes.count - self.no_votes.count * 2  # same as (total - no_votes) - no_votes
end

上面的可能稍微快一些,但我非常怀疑它会有多大区别,在索引列上计数查询速度非常快,而且你的方法版本更容易阅读