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

tho*_*nch 13 ruby-on-rails single-table-inheritance

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

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

ObjectSpace.each_object(class<<MyParentClass;self;end)
Run Code Online (Sandbox Code Playgroud)

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

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

Pav*_*ing 26

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

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

YourClass.subclasses
Run Code Online (Sandbox Code Playgroud)

在Rails 2.3中,".subclasses"受到保护,因此我们必须使用send()以下方法调用它:

YourClass.send(:subclasses)
Run Code Online (Sandbox Code Playgroud)

  • 此外,我相信您必须在开发中预加载您的类,因为延迟加载已打开. (3认同)

seq*_*elo 14

您需要急切加载类,如下所述:https://github.com/rails/rails/issues/3364

ActionDispatch::Reloader.to_prepare do
  Rails.application.eager_load!
end
Run Code Online (Sandbox Code Playgroud)

然后你就可以使用:

YourClass.subclasses
Run Code Online (Sandbox Code Playgroud)

要么

YourClass.descendants
Run Code Online (Sandbox Code Playgroud)


小智 5

ParentClass.subclasses.map(&:name)
Run Code Online (Sandbox Code Playgroud)


Tor*_*sDB 5

在你的config/environments/development.rb

Rails.application.configure do
  config.eager_load = false
end
Run Code Online (Sandbox Code Playgroud)

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

Class.subclasses
Run Code Online (Sandbox Code Playgroud)

或者

Class. descendants
Run Code Online (Sandbox Code Playgroud)

这是子类后代之间的区别

子类:

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

Foo.subclasses # => [Bar]
Run Code Online (Sandbox Code Playgroud)

后代:

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]
Run Code Online (Sandbox Code Playgroud)


Dav*_*e G -8

假设表中至少存在以下每个对象:

Object.all.uniq{|x| x.type}.collect(&:type)
Run Code Online (Sandbox Code Playgroud)

  • 这对生产来说是一个非常非常糟糕的想法!为对象表中的每个条目(可能有数千甚至数百万行)实例化对象,然后迭代它们以发现它们的类型?*畏缩* (7认同)
  • 晚了 2 年,但值得注意的是,子类未加载的问题仅在 config.cache_classes 设置为 false 时出现,因为它仅在开发模式下。 (5认同)
  • `Object.pluck(:type).uniq` 的资源成本会更便宜,但最好的答案仍然是 `Object.subclasses` (2认同)