在 STI table/modeling 模式中,一个人如何拥有所有类型共享的类型特定属性?

In a STI table/modeling schema, how can one have type specific attributes that are shared by all types?

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

class Parent < ActiveRecord::Base
end

class A < Parent
end

class B < Parent
end

我的 STI 设置正确且运行良好!但是,我想添加 :type 特定属性,例如描述。

例如,我希望所有 A 类型的 Parent 都有描述,"I am the A type of Parent. My function is for..."

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

首先想到的是在子类上有一个特定于模型的方法。所以像:

class A < Parent

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

end

我不喜欢这个解决方案,因为这确实是关于特定类型子类的数据(而不是关于子类实例本身的数据)并且你会遇到伴随这种行为而来的所有问题(部署更改数据,等等)

这是唯一的方法吗?还是有其他我没有看到的替代方法?

如何为描述创建模型?

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 挂钩,但我确信这些不是唯一的方法。

对于你的情况,我更喜欢使用 ruby 鸭子打字,如下所示

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