简体   繁体   English

Rails中的模型继承

[英]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 . 它们具有很多相同的状态(例如sizevalue ),但是Weapon还有一些额外的东西,例如damagecriticalthreat 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的说法,对象子类型应该是可互换的-也就是说,如果我将WeaponPotionGem ,则使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM