Lister les modèles existants dans une appl ication


#1

J’aurais besoin de balayer tous mes modèles pour leur demander s’ils
respond_to? qqchose qui m’intéresse.

Je vais pas balayer toutes les classes en mémoire !

  1. Y a-t-il un moyen de lieter toutes les classes qui dérivent de
    ActiveRecord::Base ?
  2. Rails doit garder qqpart la liste des modèles mais où ?

Merci d’avance pour vos suggestions …


#2

Le 21 novembre 2008 14:13, philippe a écrit :

Je vais pas balayer toutes les classes en mémoire !

C’est faisable.

  1. Y a-t-il un moyen de lieter toutes les classes qui dérivent de
    ActiveRecord::Base ?

subclasses.

  1. Rails doit garder qqpart la liste des modèles mais où ?

Dans une variable de classe…

– Jean-François.


Rails Party à Paris dimanche 30 novembre !

http://twitter.com/underflow_


#3
  1. Rails doit garder qqpart la liste des modèles mais où ?

à noter qu’avec le système de préloading de 2.2 et en production
ta liste est normalement complète.

– Jean-François.


Rails Party à Paris dimanche 30 novembre !

http://twitter.com/underflow_


#4

2008/11/21 Jean-François Trân removed_email_address@domain.invalid

http://twitter.com/underflow_


IciMarché fédère l’e-commerce de proximité
http://icimarche.fr


#5

avec le système de préloading de 2.2 et en production ta liste est
normalement complète.

Oui mais ça doit aussi marcher en dev pour être pratiquement utilisable

subclasses.

ActiveRecord::Base.subclasses
NoMethodError: protected method `subclasses’ called for
ActiveRecord::Base:Class

La question persiste donc …


#6

Le 21 novembre 2008 14:29, philippe a écrit :

avec le système de préloading de 2.2 et en production ta liste est
normalement complète.

Oui mais ça doit aussi marcher en dev pour être pratiquement utilisable

après un temps de “warm-up”, c’est possible.

Mais théoriquement si ton appli n’appelle jamais le modèle Foo.
En mode dev, Foo ne sera jamais
chargé.

subclasses.

ActiveRecord::Base.subclasses
NoMethodError: protected method `subclasses’ called for
ActiveRecord::Base:Class

La question persiste donc …

Je ne vois pas où est le pb, il dit que la méthode est protected
pas que la méthode n’existe pas.

– Jean-François.


Rails Party à Paris dimanche 30 novembre !

http://twitter.com/underflow_


#7

Le 21 novembre 2008 14:40, philippe a écrit :

il dit que la méthode est protected pas que la méthode n’existe pas.

Effectivement ; cependant on ne la trouve pas dans “Programming
Ruby”, alors que “superclass” est documentée.
Difficile de connaitre son statut exact ?!

Peut-être que : 1/ C’est une méthode rajoutée à une classe
de base dans ActiveSupport ?

2/ C’est une méthode d’AR::B ?

3/ La magie de Rails ?

Mais théoriquement si ton appli n’appelle jamais le modèle Foo. En mode
dev, Foo ne sera jamais chargé.

Oui. Alors Rails doit
avoir un mécanisme de load-on-demand pour les modèles

doit avoir ? tu le découvres ?

(et autres classes d’ailleurs) ; c’est sur ça que j’aimerais bien me
greffer.

-- Jean-François.


Rails Party à Paris dimanche 30 novembre !

http://twitter.com/underflow_


#8

il dit que la méthode est protected pas que la méthode n’existe pas.

Effectivement ; cependant on ne la trouve pas dans “Programming Ruby”,
alors
que “superclass” est documentée.
Difficile de connaitre son statut exact ?!

Mais théoriquement si ton appli n’appelle jamais le modèle Foo. En mode
dev, Foo ne sera jamais chargé.

Oui. Alors Rails doit avoir un mécanisme de load-on-demand pour les
modèles
(et autres classes d’ailleurs) ; c’est sur ça que j’aimerais bien me
greffer.


#9

doit avoir ? tu le découvres ?

Non mais ça ne me dit pas où c’est dans les internals.


#10

Une piste qui doit pouvoir marcher (en gérant quelques exceptions liés Ã
des
modèles atypiques de plugins)

my_models = User.connection.tables.collect {|t| st = t.singularize ;
require
“#{RAILS_ROOT}/app/models/#{st}.rb” ; st.camelize.constantize }

a suivre …


#11

Une autre méthode serait de lister les tables dans la DB, a partir
desquelles il est facile de reconstituer les noms des modèles mais je
sais
pas où AR permet ça ?


#12

Bon, au cas où ça servirait à qqun voici une solution qui marche :

(je cherche la liste des modèles qui implémentent acts_as_ferret et donc
respond_to? :find_by_contents )

@@known_aaf_models = nil

def known_aaf_models
Search.connection.tables.collect do |t|
st = t.singularize
m = nil
begin
m = st.camelize.constantize
rescue NameError
begin
require “#{RAILS_ROOT}/app/models/#{st}.rb”
m = st.camelize.constantize
rescue Exception
nil # Forget about this one, it must be atypical
end
end

  @@known_aaf_models = [] if @@known_aaf_models.nil?
  @@known_aaf_models << m if m.respond_to?( :find_by_contents )

end unless @@known_aaf_models

@@known_aaf_models

end


#13

peut être :l = []
ObjectSpace.each_object(Class){|t| l << t if
t.respond_to?(:find_by_contents)}
puts l

2008/11/21 philippe lachaise removed_email_address@domain.invalid