在我的几个模型中有以下代码行:
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
发布于 2013-09-12 06:28:32
对于这个非常具体的方法,您可以使用@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.autoload_paths
( config/application.rb
)中添加要将您的关注点放在其中的路径:
config.autoload_paths += %W(#{config.root}/lib/concerns)
并将averageable.rb
模块放在该目录中。
发布于 2013-09-12 06:16:32
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
铁轨外:
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
https://stackoverflow.com/questions/18766607
复制相似问题