Listing des sous-classes ne fonctionne pas dans le script / console Ruby?
-
19-09-2019 - |
Question
Cela fonctionne:
>> class Foo
>> def xyz()
>> Foo.subclasses
>> end
>> end
=> nil
>> class Bar < Foo
>> end
=> nil
>> class Quux < Bar
>> end
=> nil
>> Foo.new.xyz()
=> ["Quux", "Bar"]
Mais cela ne fonctionne pas. User
est une classe dans mon 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
Mais cela ne!
>> Foo.subclasses
=> ["Quux", "Bar"]
Qu'est-ce qui se passe ici? Comment puis-je énumérer les sous-classes de User
?
La solution
est sous-classes surchargées et communiquées protégées dans base.rb. Voir 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 (ligne 1855 définit des sous-classes de méthodes, ligne 1757, il est protégé).
Vous pouvez faire la même chose pour l'utilisateur que vous avez fait pour Foo:. Ajouter une méthode xyz ()
Autres conseils
Vous n'avez pas besoin redéclarer (comme dans la réponse de Tim ) ou fournir une méthode d'assistance (comme dans réponse Rutger). Vous avez juste besoin de changer l'autorisation de la méthode (qui, étant une méthode de classe, nécessite quelques manigances):
class User < ActiveRecord::Base
class <<self
public :subclasses
end
end
Juste pour contourner les droits d'accès et ne pas changer quoi que ce soit, pensez à utiliser la méthode #send qui a accès à des méthodes privées.
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