Получить список/массив дочерних классов из однонаправленного наследования в Rails?

У меня есть целая куча дочерних классов, которые наследуются от родительского класса через однонаправленное наследование в моем приложении Rails. Мне нужен способ получить массив всех дочерних классов, которые наследуются от основного класса.

Я попробовал следующую команду с одной связью, которую я нашел в другом ответе SO, но возвращает только родительский класс.

ObjectSpace.each_object(class<<MyParentClass;self;end)

Есть ли какой-либо чистый способ сделать это?

EDIT: По-видимому, Rails только ленивы нагружает дочерние классы при вызове в режиме Dev и, возможно, в зависимости от версии Rails. Однако первый ответ должен работать с Rails 3.1 и выше в режиме Prod.

Ответ 1

Предполагая, что по крайней мере один из каждого из существующих объектов в таблице:

Object.all.uniq{|x| x.type}.collect(&:type)

Ответ 2

Rails расширяет Ruby Class с помощью метода подклассов().

В Rails 3 вы можете вызвать его напрямую:

YourClass.subclasses

В Rails 2.3 ".subclasses" защищен, поэтому мы должны позвонить ему с помощью send():

YourClass.send(:subclasses)

Ответ 3

Вам нужно загружать классы, как указано в: https://github.com/rails/rails/issues/3364

ActionDispatch::Reloader.to_prepare do
  Rails.application.eager_load!
end

Затем вы сможете использовать:

YourClass.subclasses

или

YourClass.descendants

Ответ 4

ParentClass.subclasses.map(&:name)

Ответ 5

Это будет сделано в одном запросе SQL:

# SELECT DISTINCT type FROM objects
Object.uniq.pluck(:type)

Ответ 6

Обратите внимание, что это более эффективный способ реализации метода Dave G выше..

Object.select(:type).map(&:type).uniq

Это сначала отправляет маршалированные объекты, которые имеют только атрибут "type" из БД, который берет WAY меньше памяти, а затем сбрасывает только типы в массив, который вы можете затем uniq. Я уверен, что есть еще более эффективный чистый SQL-способ сделать это, хотя.