在我的应用中,我可以计算Result
s进行测量。结果模型使用单表继承来定义不同的结果类型,每种结果类型都实现calculate
方法。现在,我需要在其他人之前计算一些结果。例如:
class Result < ActiveRecord::Base
belongs_to :measurement
def calculate
raise "#calculate is abstract. Implement this method in one of the subclasses."
end
def self.depends_on(args)
# what to do here?
end
end
一个子类看起来像:
# The total duration in milliseconds
class TotalDuration < Result
depends_on :EventList # calculate the EventList result first
def calculate
# how do I find out what I depend on?
# only then do the actual calculation
end
end
正如您所看到的,我已经添加了depends_on
类方法,我希望通过该方法表示TotalDuration
结果需要之前计算的EventList
结果。< / p>
但是如何在运行时访问信息,例如当我在calculate
时?例如,我可以先计算依赖关系,然后继续。
我会假设使用类级属性(例如@@depends_on
)不被认为是好风格?
答案 0 :(得分:1)
我会创建一个连接模型,允许Result
到have_many
依赖结果的任何特定实例。
然后在您的计算方法中,对于具有依赖关系的结果,您首先要求从依赖结果中进行计算,然后再继续进行自己的计算。
通过自然递归,如果任何相关结果具有进一步的依赖性......这自然会过滤链。
答案 1 :(得分:1)
def self.depends_on(*args)
define_method("calculate_dependencies") do
args.each do |arg|
measurement.results.where(type: arg.to_s).each { |result| result.calculate unless result.value }
end
end
end
这样,我只需要打电话
def calculate
calculate_dependencies
# other stuff
end
在我的孩子模特中。我甚至可以使用依赖结果的名称定义一个新方法:
define_method("#{arg.to_s.underscore}") do
results = measurement.results.where(type: arg.to_s).limit(1)
result = results.first if results.any?
result.calculate if result.value.nil?
result
end
那样,我可以这样做:
depends_on :EventList
def calculate
# no need for calculate_dependencies
event_list # <= this is the result I depend on, already calculated
end