[英]how to DRY this code?
我的几个模型中都有以下代码行:
def average(scores)
# get average of scores and round to two decimal places
average = scores.inject{ |sum, el| sum + el }.to_f / scores.size
average.round(2)
end
我尝试将其放入各种帮助程序文件中,但取得了不同的成功-但问题并不在于我无法正常工作,而是要包含一些丑陋的代码和/或其他文件(模块等)所有模型中都采用这种方法-这引起了一些危险。 不应该那么难。
助手代码对于控制器和视图来说很容易,但是对于模型来说确实是违反直觉的-同时,在4个地方(字面上)拥有完全相同的代码似乎很愚蠢。 晾干的最佳方法是什么?
更新
我想在每个模型的方法中使用average
帮助程序-在每种情况下都不同,但是对于最后一行,所有内容都进行了平均-像这样:
def avg_for(student)
scores = []
self.evals.map do |student_id, evals|
evals.select {student_id == student.id}.each do |eval|
scores << eval.score
end
end
average(scores) #here!
end
http://api.rubyonrails.org/classes/ActiveRecord/Calculations.html#method-i-average
class Student < ActiveRecord::Base
has_many :evals
def average_score
evals.average(:score)
end
end
在Rails之外:
def average(score)
(score.inject(:+).to_f / score.size).round(2)
end
编辑
使用您的avg_for
方法:
def avg_for(student)
evals.where(student: student).average(:score)
end
对于这种非常特定的方法,可以使用@delba答案。
要确切回答有关跨模型共享方法的问题,这是一项令人关注的工作。
在rails-4中,关注点成为顶级公民,并自动创建目录app/models/concerns
和app/controllers/concerns
。
您可以在app/concerns/averageable.rb
添加类似的内容:
module Averageable
def average(scores)
# get average of scores and round to two decimal places
average = scores.inject{ |sum, el| sum + el }.to_f / scores.size
average.round(2)
end
end
然后,在模型中使用它:
class User < ActiveRecord::Base
include Averageable
end
您关注的方法将适用于包含该方法的任何模型。
编辑:
要在rails-3中执行相同的操作,请在config/application.rb
config.autoload_paths
添加您要关注的路径:
config.autoload_paths += %W(#{config.root}/lib/concerns)
并将averageable.rb
模块放在该目录中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.