Подтвердить что ты не робот

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

4b9b3361

Ответ 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:)