Rails:如何通过存储类型在STI层次结构中创建类的实例?

时间:2009-07-15 23:57:26

标签: ruby-on-rails activerecord

假设我使用STI模式来持久化“Transaction”的几个不同子类,其子类为“ActiveRecord”

我的子类可能包含“HighPriorityTransaction”和“LowPriorityTransaction”,rails将使用“type”列存储在“transactions”表中。每个子类都有不同的before_save回调实现。

我的问题是如何通过类型字符串值创建这些类的实例?

我想我会从组合框中获取类型,实例化该类型,并让对象通过多态来处理before_save回调。关于这一点的任何其他想法也将受到赞赏。

谢谢!

3 个答案:

答案 0 :(得分:0)

我找到了一个我认为可以分享的解决方案:

type = Kernel.const_get("type_string") 

#which in this case might be 
#type = Kernel.const_get("HighPriorityTransaction")

transaction = type.new

答案 1 :(得分:0)

该方法的一个问题是,如果客户端碰巧知道其名称,它允许客户端使应用程序中的任何类被实例化,除非您在控制器中明确防范它。以下是一种可行的替代方案。它在Transaction类上创建一个“registry”属性,用于将子类名称映射到子类对象。

class Transaction

  class << self
    attr_reader :registry

    def inherited(sub)
      @registry ||= {}
      @registry[sub.name] = sub
    end
  end
end

class HighPriorityTransaction < Transaction; end

Transaction.registry["HighPriorityTransaction"].new.class # HighPriorityTransaction

答案 2 :(得分:0)

这可能与您正在寻找的内容相符:

@transaction = "HighPriorityTransaction".camelize.constantize.new