从Rails中的单表继承获取子类的列表/数组?

时间:2012-05-10 13:54:54

标签: ruby-on-rails single-table-inheritance

我有一大堆子类,它们通过我的Rails应用程序中的单表继承从父类继承。我想要一种方法来获取从主类继承的所有子类的数组。

我尝试了在另一个SO答案中找到的以下单链接命令,但它只返回父类。

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

有没有干净的方法可以做到这一点?

修改 显然Rails只在惰性模式下调用延迟加载子类,并且可能根据Rails版本生成。但是,第一个答案应该适用于Prod模式下的Rails 3.1及更高版本。

7 个答案:

答案 0 :(得分:25)

Rails使用subclasses()方法扩展Ruby Class

在Rails 3中,您可以直接调用它:

YourClass.subclasses

在Rails 2.3中,“。subclasses”受到保护,因此我们必须使用send()来调用它:

YourClass.send(:subclasses)

答案 1 :(得分:13)

您需要急切加载课程,如:https://github.com/rails/rails/issues/3364

中所述
ActionDispatch::Reloader.to_prepare do
  Rails.application.eager_load!
end

然后你就可以使用:

YourClass.subclasses

YourClass.descendants

答案 2 :(得分:4)

ParentClass.subclasses.map(&:name)

答案 3 :(得分:3)

在您的 config / environments / development.rb

Rails.application.configure do
  config.eager_load = false
end

U可以将 false 更改为 true ,然后在控制台中执行

Class.subclasses

Class. descendants

这是子类后代

之间的区别

子类:

class Foo; end
class Bar < Foo; end
class Baz < Bar; end

Foo.subclasses # => [Bar]

后裔:

class C; end
C.descendants # => []

class B < C; end
C.descendants # => [B]

class A < B; end
C.descendants # => [B, A]

class D < C; end
C.descendants # => [B, A, D]

答案 4 :(得分:1)

这将在一个SQL查询中执行:

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

答案 5 :(得分:0)

注意,它们是实现上述Dave G方法的更有效方法。

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

这首先发送只有来自数据库的“type”属性的封送对象,这样可以减少内存,然后只将类型提取到一个数组中,然后你可以 uniq 。我确信有一种无限高效的纯SQL方法可以做到这一点。

答案 6 :(得分:-6)

假设表中至少存在一个对象:

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