[英]Model Inheritance in Rails
I have a class Item
and another Weapon
. 我有一个Class
Item
和另一个Weapon
。 They share a lot of the same state (eg size
, value
), but Weapon
has some extra stuff, like damage
, critical
, and threat
. 它们具有很多相同的状态(例如
size
, value
),但是Weapon
还有一些额外的东西,例如damage
, critical
和threat
。 In raw Ruby, I'd extract these common attributes to a module and compose both of them, or I might subclass Weapon
from Item
and put the common state in the superclass. 在原始Ruby中,我会将这些通用属性提取到模块中并组成它们,或者我可以从
Item
继承Weapon
子类,然后将通用状态放入超类。
Except I'm using Rails. 除了我正在使用Rails。 Single-Table Inheritance doesn't seem like a nice solution as
Weapon
has a number of attributes not in Item
, and I don't fancy all the empty DB columns. 单表继承似乎不是一个很好的解决方案,因为
Weapon
有许多不在Item
的属性,我也不喜欢所有空的DB列。 Polymorphic association doesn't right either, as it seems to be more useful for sharing associations between models, rather than sharing state. 多态关联也不正确,因为它似乎对于共享模型之间的关联比共享状态更有用。 Using a Concern: much the same issue.
使用关注点:同样的问题。
Is there anything in Rails that allows me to extend the state of a single model in another, while building an extra table for any additional attributes? Rails中有什么可以让我在另一个模型中扩展单个模型的状态,同时为任何其他属性构建一个额外的表?
Here's a code example of what I'd like in raw Ruby: 这是我想要原始Ruby的代码示例:
class Item
attr_accessor :value, :weight, item_type
class Weapon < Item
attr_accessor :damage, :threat, :critical, :weapon_type
Weapon.new(value: 12) # => weapon instance with value 12
In Rails, can try adding item_id
to Weapon
- but then I can't do Weapon.new(value: 12)
, I'd have to do Weapon.new(item: Item.new(value: 12))
. 在Rails中,可以尝试将
item_id
添加到Weapon
-但是我不能做到Weapon.new(value: 12)
,我必须要做Weapon.new(item: Item.new(value: 12))
。
TL;DR this violates the Liskov Substitution Principle , so I shouldn't do it. TL; DR违反了Liskov替换原则 ,所以我不应该这样做。
According to Liskov, object subtypes should be interchangeable - that is, a method that uses an instance of the Weapon
class should work if I switch the Weapon
for a Potion
or a Gem
. 根据Liskov的说法,对象子类型应该是可互换的-也就是说,如果我将
Weapon
为Potion
或Gem
,则使用Weapon
类实例的方法应该可以使用。 Clearly, that's not the case: so from an OOP angle, I shouldn't be using Inheritance here. 显然,事实并非如此:所以从OOP角度来看,我不应该在这里使用继承。
Thanks for the debate! 感谢您的辩论!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.