使用Ruby on Rails对属性求和的最佳方法

时间:2015-10-11 11:44:52

标签: ruby-on-rails ruby

在我正在创建的Web应用程序中,我必须为每个用户计算得分。我目前正在以这种方式计算得分:

class Opinion < ActiveRecord::Base
  belongs_to :hero
  def score_value
    self.note * (self.end_date - self.start_date)
  end
end

class User < ActiveRecord::Base
  has_many :opinions
  def update_score
    self.score = 0
    self.opinions.each { |opinion| self.score += opinion.score_value }
    self.save
  end
end

但我觉得这不是最好的方法。有没有更好的方法呢?

2 个答案:

答案 0 :(得分:1)

好吧,我建议在#update_score中使用所有红宝石力:

class User < ActiveRecord::Base
  has_many :opinions
  def update_score
    self.score = self.opinions.map(&:score_value).inject(0, &:+)
    self.save
  end
end

您可以做的另一件事是将一些计算移动到数据库:

class User < ActiveRecord::Base
  has_many :opinions
  def update_score
    self.score = opinions.pluck(:note, 'DATEDIFF(end_date, start_date)').map do |note, days|
      note * days 
    end.inject(0, &:+)
    self.save
  end
end

这只是一种性能改进,我不认为它很优雅。

答案 1 :(得分:0)

你可以在这里做出多项改进,我想要的是

在属性发生变化时重新计算分数

class Opinion
  before_save :update_score

  def update_score
    return unless note_changed? || end_date_changed? || start_date_changed?
    self.note * (self.end_date - self.start_date)
  end
end

更新用户模型

中的分数计算方式
class User
  def update_score
    self.score = self.opinions.sum(:score)
  end
end