0

У меня есть класс Item и еще Weapon. Они имеют много общего состояния (например, size, value), но Weapon имеет некоторые дополнительные материалы, такие как damage, critical и threat. В raw Ruby я извлечу эти общие атрибуты в модуль и составлю их оба, или я мог бы подкласса Weapon от Item и поставить общее состояние в суперкласс.Наследование моделей в рельсах

За исключением использования рельсов. Одностраничное наследование не похоже на приятное решение, так как Weapon имеет ряд атрибутов не в Item, и мне не нравятся все пустые столбцы БД. Полиморфная ассоциация также не подходит, так как кажется более полезной для обмена ассоциациями между моделями, а не для совместного использования. Использование Концерна: почти такая же проблема.

Есть ли что-нибудь в Rails, которое позволяет мне продлить состояние одной модели в другой, создав дополнительную таблицу для любых дополнительных атрибутов?

Вот пример кода, что я хотел бы в сыром 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 

В Rails, можно попробовать добавить item_id к Weapon - но я не могу сделать Weapon.new(value: 12), я должен был бы сделать Weapon.new(item: Item.new(value: 12)).

+0

вышеуказанные модели, которые вы создали, абсолютно прекрасны. Вы можете вызвать 'Weapon.new (значение: 12)' и 'Item.new (значение: 12)' –

+0

Да, в Ruby. Не в Rails, без использования STI, и оставляя множество столбцов БД в таблице 'items'. –

+2

Нет простого способа наследования, когда вам приходится разговаривать с базами данных, я также не вижу, какие выгоды вы получаете от наследования здесь, даже если бы было возможно, что бы вы назвали эту таблицу в базе данных, я думаю, оставив модели отлично, и сделает код-код менее запутанным. – bjhaid

ответ

0

TL; DR это нарушает Liskov Substitution Principle, поэтому я не должен этого делать.

В соответствии с Лиск, объект подтипы должны быть взаимозаменяемыми - то есть метод, который использует экземпляр класса Weapon должен работать, если я переключить Weapon для Potion или Gem. Ясно, что это не так: поэтому из-за угла ООП я не должен использовать Наследование здесь.

Спасибо за дебаты!

Смежные вопросы