我在哪里存储传递给Rails模型中的宏方法的值?

时间:2014-08-22 07:16:51

标签: ruby-on-rails rails-activerecord

在我的应用中,我可以计算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)不被认为是好风格?

2 个答案:

答案 0 :(得分:1)

我会创建一个连接模型,允许Resulthave_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