简体   繁体   English

如何在Rails模型中存储传递给宏方法的值?

[英]Where do I store the values passed to a macro method in a Rails model?

In my app, I can calculate Result s for a measurement. 在我的应用中,我可以计算测量的Result The result model uses Single Table Inheritance to define different result types, each of which implements a calculate method. 结果模型使用“单表继承”来定义不同的结果类型,每种类型都实现一个calculate方法。 Now, I need to calculate some results before others. 现在,我需要先计算一些结果。 Example: 例:

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

One subclass could look like: 一个子类可能类似于:

# 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

As you can see, I've already included a depends_on class method, with which I'd like to express that the TotalDuration result needs the EventList result calculated before. 如您所见,我已经包含了depends_on类方法,我想用该方法表示TotalDuration结果需要之前计算出的EventList结果。

But how do I access the information at runtime, eg when I'm inside calculate ? 但是如何在运行时访问信息,例如当我进入calculate There for example I could calculate the dependency first, then continue. 例如,我可以先计算依赖性,然后继续。

I would assume that using class level attributes (eg, @@depends_on ) are not considered good style? 我会假设使用类级别的属性(例如@@depends_on )不被认为是好的样式?

I would create a join model which allows any particular instance of Result to have_many dependent results. 我将创建一个have_many模型,该模型允许Result任何特定实例具有与have_many相关的结果。

Then in your calculate method for a result with dependencies you first ask for the calculations from the dependent results before continuing with your own calculation. 然后,在您的具有依存关系的结果的计算方法中,首先请从依存结果中进行计算,然后再继续自己的计算。

Through natural recursion, if any of those dependent results had further dependencies ... this would naturally filter up the chain. 通过自然递归,如果这些依赖结果中的任何一个具有进一步的依赖关系……这自然会过滤掉整个链。

I solved it like this: 我这样解决了:

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

This way, I only have to call 这样我只需要打电话

def calculate
  calculate_dependencies
  # other stuff
end

in my child models. 在我的孩子模型中。 I could even go as far as defining a new method with the name of the dependent result: 我什至可以用依赖结果的名称来定义一个新方法:

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

That way, I could do: 这样,我可以做到:

depends_on :EventList

def calculate
  # no need for calculate_dependencies
  event_list  # <= this is the result I depend on, already calculated
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM