Pergunta

Isso funciona:

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

Mas isso não. User é uma aula no meu aplicativo.

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

Mas isso faz!

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

O que está acontecendo aqui? Como eu listaria as subclasses de User?

Foi útil?

Solução

As subclasses são substituídas e feitas protegidas em base.rb. Ver 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 (A linha 1855 define subclasses de método, a linha 1757 o torna protegido).

Você pode fazer o mesmo para o usuário que fez para Foo: Adicione um método xyz ().

Outras dicas

Você não precisa redeclare (como em Resposta de Tim) ou fornecer um método auxiliar (como em Resposta de Rutger). Você só precisa alterar a permissão do método (que, sendo um método de classe, requer algumas travessuras):

class User < ActiveRecord::Base

  class <<self
    public :subclasses
  end

end

Apenas para contornar os direitos de acesso e não alterar nada, considere usar o método #send que tem acesso a métodos privados.

User.send(:subclasses)
tables = ActiveRecord::Base.connection.tables {|t| t.classify.constantize rescue nil}.compact
subclasses = tables.map do |table|
  table.singularize.classify.constantize
end
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top