【问题标题】:Rails ActiveRecord - inheriting from a base class with no tableRails ActiveRecord - 从没有表的基类继承
【发布时间】:2010-08-20 16:44:59
【问题描述】:

我想做的是为我的一些模型创建一个基类,这些模型具有一些默认的活动记录行为:

class Option < ActiveRecord::Base
  has_many :products

  def some_method
    #stuff
  end

  #etc..etc..
end

class ColorOption < Option
  #stuff...
end


class FabricOption < Option
  #stuff...
end

但是,我希望 ColorOption 和 FabricOption 都在各自的表格中。我不想使用 STI 或有一个基类“选项”的表。我让它工作的唯一方法是使用一些非继承元编程魔法。但我想知道是否有办法告诉 AR 基类不需要表。它只是为了提供额外的行为,并像往常一样将其他子类放在自己的表中。

谢谢, 克雷格

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    你想要的是一个抽象类:

    class Option < ActiveRecord::Base
      self.abstract_class = true
    end
    
    class ColorOption < Option
      ...
    end
    
    class FabricOption < Option
      ...
    end
    

    【讨论】:

    • 我必须设置表名,还是 AR 可以推断?
    • 不需要 set_table_name,至少在 Rails 3.2 中。
    • 将此与 Szymon Przybył 的方法相结合给了我最好的结果。我在抽象类中添加了以下内容,以自动处理为继承类设置表名: def self.inherited(child) child.table_name = child.name.underscore.pluralize end
    • 我在 rails 2.3 中需要的只是“abstract_class”部分。干杯!
    【解决方案2】:

    看起来像是您包含的模块的案例。

    module Option
      def self.included(base)
        base.has_many :products
      end
    
      # other instance methods
    end
    
    class ColorOption < ActiveRecord::Base
      include Option
      set_table_name '???' # unless ColorOption / FabricOption have same table -> move to Option module
    
      #stuff...
    
    end
    
    
    class FabricOption < Option
      include Option
      set_table_name '???' # unless ColorOption / FabricOption have same table -> move to Option module
    
      #stuff...
    end
    

    更多信息:http://mediumexposure.com/multiple-table-inheritance-active-record/

    【讨论】:

    • 是的,我尝试了该模块,但该模块看不到活动记录方法,例如 has_many :products。它说方法是未定义的。
    • fregas:确保包含任何类方法调用,例如 has_many 或 Stephan 在他的示例中的 self.included 方法中的验证
    • 啊 self.included 指的是包含模块的类。太好了,我试试看!
    • 甜,效果很好!耶红宝石!比元编程更优雅...
    • 你在最后一个类定义中没有错字吗,它应该继承自ActiveRecord::Base而不是Option
    【解决方案3】:

    我有类似的问题,但我也想改变 AR 为我的模型设置 table_name 的方式,例如 MyProject 模型的表名是“MY_PROJECT”。

    正如@FFrançois 所说,我通过创建抽象 AR 类来实现它,并使用继承的方法来更改表名,如下所示:

    class MyModel < ActiveRecord::Base
      self.abstract_class = true
    
      def self.inherited(subclass)
        subclass.table_name = subclass.name.underscore.upcase
      end
    end
    
    class MyProject < MyModel
    end
    

    现在 MyProject.table_name 给出 MY_PROJECT :)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-12
      相关资源
      最近更新 更多