Ответ 1
Вы можете добиться этого, отключив inheritance_column
для модели, например:
class AnotherSection < Section
# disable STI
self.inheritance_column = :_type_disabled
end
В Rails 3.2.6 у меня есть класс, который наследуется от ActiveRecord:: Base:
class Section < ActiveRecord::Base
...
end
Когда я наследую этот класс, Rails предполагает, что я хочу STI:
class AnotherSection < Section
..Rails assumes I have a type field, etc...
end
Я хочу унаследовать от класса Section
и использовать подкласс как обычный подкласс Ruby без магии Rails STI.
Есть ли способ предотвратить STI при подкласце из модели ActiveRecord::Base
?
Вы можете добиться этого, отключив inheritance_column
для модели, например:
class AnotherSection < Section
# disable STI
self.inheritance_column = :_type_disabled
end
Принятый ответ определенно будет работать, но рекомендуемый (смею сказать "правильный":) способ установить abstract_class
:
class Section < ActiveRecord::Base
self.abstract_class = true
end
Единственная полностью поддерживаемая стратегия хранения наследования ActiveRecord - это STI. Тем не менее, вы можете имитировать конкретное наследование класса на свой страх и риск. Конкретное наследование класса-таблицы с абстрактным суперклассом отлично работает, как указано smathy.
НО... Если вы хотите сделать AnotherSection просто обычным классом (который не будет сохраняться в базе данных), вы можете отключить столбец дискриминатора (как предложено Veraticus). Однако, если вы сохраните AnotherSection, он будет сохранен в той же таблице, что и раздел, и вы не сможете отличить их друг от друга. Кроме того, если вы используете AnotherSection, чтобы найти раздел, он вернет AnotherSection, нарушив первоначальный экземпляр:
#create a Section and saves it
sect = Section.create()
sect.save()
#retrieve the Section as a AnotherSection, breaking polymorphism...
sect = AnotherSection.find(sect.id)
# another section is more than a section, it is inconsistent.
Если AnotherSection не предназначено для сохранения, самый безопасный путь для переопределения операций сохранения, таких как save() и find():
class AnotherSection < Section
# disable STI, as pointed by Veraticus
self.inheritance_column = :_type_disabled
# disable save and finding
def save(*args)
#exception? do nothing?
end
def find(*args)
#exception? do nothing?
end
def find_by(*args)
#exception? do nothing?
end
# this does not stops here! there is first, last, and even a forty_two finder method! not to mention associations...
end
в двух словах, вы можете это сделать, но вы НЕ ДОПУСКАЕТЕ. Риск очень высок. Вы должны рассмотреть другой вариант, например, использовать MIXIN вместо наследования.