Rails:仅列出ActiveRecord :: Base子类的直接子类

时间:2014-03-13 02:41:20

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

我试图获取一个继承自ActiveRecord::Base;的类的所有直接子类,即只有直接从基类继承的类,而不是从子类的子类。但是这样做的正常方式似乎不适用于ActiveRecord::Base子类。

通常,这是使用Class::subclasses方法完成的:

class C1; end
class C2 < C1; end
class C3 < C2; end
C1.subclasses
#=> [C2]

我想为ActiveRecord::Base子类执行此操作:

class T1 < ActiveRecord::Base; end
class T2 < T1; end
class T3 < T2; end
T1.subclasses
#=> [T2(Table doesn't exist), T3(Table doesn't exist)]

我得到了孩子和孙子课程,这不是我想要的!对于已定义表的类,会发生相同的基本行为。

这已经指出ActiveRecord::Base子类的作用有点不同,因为覆盖了inspect()以提供表名。因此,猜测它们也会超越子类并不是太过分了。

  1. 是否可以只获取一个直接子类的列表 ActiveRecord::Base子类?
  2. 他们为什么要改变subclasses()

2 个答案:

答案 0 :(得分:1)

根据这个:

http://apidock.com/rails/ActiveRecord/Base/subclasses/class

ActiveRecord::Base有一个subclasses方法只返回descendants的值直到版本3.1(实际上这说3.0.9,但我认为这是它被弃用的时候;你可以直到3.1)才能在源代码中看到它。 descendants返回接收者<的所有内容(您观察到的行为)。

以下是删除它的提交:

https://github.com/rails/rails/commit/9b610049bb4f73dbcdc670879683ec2a1a2ab780

Rails 3.1及之后的行为应如您所描述的那样。如果您使用的是Rails&gt; = 3.1,那么我不确定如何解释您所看到的内容。

答案 1 :(得分:1)

上述评论中重新发布的代码,因为评论不允许良好的格式化。这适用于我的目的:

class T1 < ActiveRecord::Base
  def self.my_subclasses
    Object.singleton_class.instance_method(:subclasses).bind(self).call
  end
end