[英]Best way to sum attributes with Ruby on Rails
In a web application I'm currently creating, I have to calculate a score for each user. 在我当前正在创建的Web应用程序中,我必须为每个用户计算一个分数。 I'm currently calculating the score this way :
我目前正在以这种方式计算分数:
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
But I have the feeling that's not the best way to do it. 但是我觉得这不是最好的方法。 Is there any better way to do it ?
有什么更好的办法吗?
Well, I can suggest using all ruby power in #update_score
: 好吧,我建议在
#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
Another thing you could do is to move some calculation to database: 您可以做的另一件事是将一些计算移至数据库:
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
This is just a perfomance improvement and I don't think its elegant. 这只是性能上的改进,我认为它并不优雅。
There are multiple improvements you could make here, what I would go for is 您可以在此处进行多项改进,我要做的是
Recalculate the score when attributes are changes 属性更改时重新计算分数
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
Update how score is calculated in User model 更新用户模型中分数的计算方式
class User
def update_score
self.score = self.opinions.sum(:score)
end
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.