在STI表/建模模式中,如何具有所有类型共享的类型特定属性?

时间:2017-07-27 11:40:16

标签: ruby-on-rails data-modeling single-table-inheritance

我有一个设置,其中有多个模型继承自Base模型 - 标准单表继承:

class Parent < ActiveRecord::Base
end

class A < Parent
end

class B < Parent
end

我的STI设置正确且效果很好!但是,我想添加:类型特定属性,如描述。

例如,我希望所有A类型的父类都有描述,&#34;我是A类型的父类。我的功能是......&#34;

我想避免反复复制数据(例如,让A的每个实例存储相同的描述)。

首先想到的是在Subclass上有一个特定于模型的方法。如下所示:

class A < Parent

  def self.description
    "I am the A type of Parent. My function is for..."
  end

end

我不喜欢这个解决方案,因为这实际上是特定类型的子类(而不是子类实例本身)上的数据,并且您得到了产生此行为所带来的所有问题(部署以更改数据,等)

这是唯一的方法,还是我没有看到的替代方案?

2 个答案:

答案 0 :(得分:0)

如何为描述创建模型?

class Description < ActiveRecord::Base
  has_many :as
end

class A < Parent
  belongs_to :description

  before_save { description_id = 1 }
end

这样,您可以管理数据库中description的内容,并可以通过Web界面或迁移对其进行修改。此外,您可以轻松地为不同的子类添加不同的描述,如果需要,甚至可以为每个实例更改它们。

这种方法的一个缺点是您需要使用正确的描述创建模型。一个可能的解决方案可能是before_savebefore_create钩子,但我确信这些不是唯一的方法。

答案 1 :(得分:0)

对于您的情况,我更喜欢使用红宝石鸭打字如下

class ParentAll
  def talk(object1)
    object1.talk
  end
end

class A < ParentAll
  def talk
    puts 'I am the A type of Parent. My function is for...'
  end
end

class B < ParentAll
  def talk
    puts 'I am the B type of Parent. My function is for...'
  end
end

@parent = ParentAll.new
puts 'Using the A'
@parent.talk(A.new)
  # this will output talk from A

puts 'Using the B'
@parent.talk(B.new)
  # this will output talk from B