1

这有效:

>> class Foo 
>>   def xyz()
>>     Foo.subclasses
>>   end
>> end
=> nil
>> class Bar < Foo
>> end
=> nil
>> class Quux < Bar
>> end
=> nil
>> Foo.new.xyz()
=> ["Quux", "Bar"]

但这不是。User是我的应用程序中的一个类。

>> User.subclasses
NoMethodError: protected method `subclasses' called for #<Class:0x20b5188>
    from [...]/vendor/rails/activerecord/lib/active_record/base.rb:1546:in `method_missing'
    from (irb):13

但这确实!

>> Foo.subclasses
=> ["Quux", "Bar"]

这里发生了什么?我将如何列出 的子类User

4

4 回答 4

2

子类在 base.rb 中被覆盖并受到保护。请参阅http://www.google.com/codesearch/p?hl=en&sa=N&cd=1&ct=rc#m8Vht-lU3vE/vendor/rails/activerecord/lib/active_record/base.rb&q=active_record/base.rb(行1855 定义了方法子类,第 1757 行使其受到保护)。

您可以对 User 执行与 Foo 相同的操作:添加 xyz() 方法。

于 2009-07-28T17:40:11.003 回答
1

您不需要重新声明(如Tim 的回答提供辅助方法(如Rutger 的回答)。您只需要更改方法的权限(作为类方法,需要一些恶作剧):

class User < ActiveRecord::Base

  class <<self
    public :subclasses
  end

end
于 2009-07-28T18:06:57.923 回答
1

只是为了解决访问权限而不更改任何内容,请考虑使用可以访问私有方法的 #send 方法。

User.send(:subclasses)
于 2011-10-07T15:35:32.063 回答
0
tables = ActiveRecord::Base.connection.tables {|t| t.classify.constantize rescue nil}.compact
subclasses = tables.map do |table|
  table.singularize.classify.constantize
end
于 2019-08-22T04:05:13.383 回答