Rails ActiveRecord - наследование из базового класса без таблицы
То, что я хочу сделать, - это базовый класс для некоторых моих моделей, которые имеют поведение по умолчанию по умолчанию:
class Option < ActiveRecord::Base
has_many :products
def some_method
#stuff
end
#etc..etc..
end
class ColorOption < Option
#stuff...
end
class FabricOption < Option
#stuff...
end
Однако я хочу, чтобы ColorOption и FabricOption были в своих собственных таблицах. Я НЕ хочу использовать STI или иметь таблицу для базового класса "Option". Единственный способ, с помощью которого я работал, - это использовать магию метапрограммирования без наследования. Но я задавался вопросом, есть ли способ сообщить AR, что базовому классу не нужна таблица. Его просто там для дополнительного поведения и поместить другие подклассы в свою таблицу, как обычно.
Спасибо,
Craig
Ответы
Ответ 1
Похож на случай для модуля, который вы включили.
module Option
def self.included(base)
base.has_many :products
end
# other instance methods
end
class ColorOption < ActiveRecord::Base
include Option
set_table_name '???' # unless ColorOption / FabricOption have same table -> move to Option module
#stuff...
end
class FabricOption < Option
include Option
set_table_name '???' # unless ColorOption / FabricOption have same table -> move to Option module
#stuff...
end
Дополнительная информация: http://mediumexposure.com/multiple-table-inheritance-active-record/
Ответ 2
То, что вы хотите, это абстрактный класс:
class Option < ActiveRecord::Base
self.abstract_class = true
end
class ColorOption < Option
...
end
class FabricOption < Option
...
end
Ответ 3
У меня была схожая проблема, но я также хотел изменить способ, которым AR устанавливал имя таблицы для моих моделей, например, модель MyProject имела бы табличное имя "MY_PROJECT".
Я достиг этого, создав абстрактный AR-класс, как сказал @FFrançois, и с унаследованным методом, где я меняю имя таблицы, например:
class MyModel < ActiveRecord::Base
self.abstract_class = true
def self.inherited(subclass)
subclass.table_name = subclass.name.underscore.upcase
end
end
class MyProject < MyModel
end
Теперь MyProject.table_name дает MY_PROJECT:)