列表子类在Ruby脚本/控制台中不起作用?

时间:2009-07-28 17:24:24

标签: ruby-on-rails ruby subclass groovy-console

这有效:

>> 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 个答案:

答案 0 :(得分: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行使其受保护)。

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

答案 1 :(得分:1)

您无需重新声明(如在Tim's answer中)提供辅助方法(如Rutger's answer中所述)。您只需要更改方法的权限(作为类方法,需要一些恶作剧):

class User < ActiveRecord::Base

  class <<self
    public :subclasses
  end

end

答案 2 :(得分:1)

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

User.send(:subclasses)

答案 3 :(得分:0)

tables = ActiveRecord::Base.connection.tables {|t| t.classify.constantize rescue nil}.compact
subclasses = tables.map do |table|
  table.singularize.classify.constantize
end