简体   繁体   English

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

[英]How can I compute a conditional sum in my model?

Say I want something like this in Rails: 说我想是这样的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. What have I basically done wrong in the code above? 在上面的代码中,我基本上做错了什么? (I realize it's probably terrible in numerous ways.) (我意识到这可能在很多方面都非常糟糕。)
  2. What's the correct way to do this from a Rails standpoint? 从Rails的角度来看,这样做的正确方法是什么?
  3. What considerations should I be mindful of from a database standpoint? 从数据库的角度来看,我应该注意哪些注意事项? (eg, even if code like the above were possible, I'm guessing it would be excessive on the DB side. But naturally I'm not really sure.) (例如,即使上面的代码可能的,但我猜想在数据库方面它可能会过多。但是自然地,我不确定。)

class Proposal < ActiveRecord::Base 类Proposal <ActiveRecord :: Base

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

end 结束

thanks, Anubhaw 谢谢,Anubhaw

Considering the database loading i recommend to implement a custom counter cache. 考虑到数据库加载,我建议实现自定义计数器缓存。 I would do like this: 我会这样:

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

Please note, you have to add two columns to your Proposal model. 请注意,您必须在Proposal模型中添加两​​列。

add_columns_migration.rb

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

I don't really see anything overtly wrong with your code. 我真的没有发现您的代码有任何明显的错误。 Though there are a number of ways to accomplish what you seem to be trying to do, your method seems like it should work fine (though I have limited experience with Arel). 尽管有很多方法可以完成您似乎想做的事情,但是您的方法似乎应该可以正常工作(尽管我对Arel的经验有限)。

Another way to go about this might be simply changing the interest_level method: 解决此问题的另一种方法可能是简单地更改interest_level方法:

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

The above might be slightly quicker, though I highly doubt it will make much difference, count queries are pretty fast on indexed columns, and your version of that method is easier to read 上面的方法可能会稍快一些,尽管我高度怀疑这会带来很大的不同,对索引列的计数查询非常快,而且该方法的版本更易于阅读

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM