views:

158

answers:

2

This works:

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

But this doesn't. User is a class in my application.

>> 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

But this does!

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

What's going on here? How would I list the subclasses of User?

+2  A: 

subclasses is overridden and made protected in base.rb. See http://www.google.com/codesearch/p?hl=en&amp;sa=N&amp;cd=1&amp;ct=rc#m8Vht-lU3vE/vendor/rails/activerecord/lib/active_record/base.rb&amp;q=active_record/base.rb (line 1855 defines method subclasses, line 1757 makes it protected).

You could do the same for User as you did for Foo: add a xyz() method.

Rutger Nijlunsing
+1  A: 

You don't need to redeclare (as in Tim's answer) or provide a helper method (as in Rutger's answer). You just need to change the permission of the method (which, being a class method, requires some shenanigans):

class User < ActiveRecord::Base

  class <<self
    public :subclasses
  end

end
James A. Rosen