2010-12-08 4 views
2

Disons que j'ai quelque chose comme çaLes différences dans les sous-classes fonctionnent entre les rails 2 et 3

class Major < ActiveRecord::Base 
    def self.my_kids 
    self.subclasses.collect {|type| type.name}.sort 
    end 
end 

class MinorOne < Major 
end 

class MinorTwo < Major 
end 

Dans Rails 2.3 Je pourrais appeler Major.my_kids et retourner un tableau des noms de sous-classe, mais dans Rails 3.0. 3 Je récupère un tableau vide, sauf si je charge les sous-classes en premier. Cela me semble faux, ai-je raté quelque chose ou est-ce nouveau pour Rails 3?

Répondre

2

Il n'y a pas de différence entre Rails 2 et 3 concernant l'utilisation de la méthode subclasses. Vous pourriez avoir cru qu'il travaillait précédemment parce que les sous-classes étaient déjà chargées. Comme Rails charge la plupart des fichiers de façon dynamique, une classe parente ne peut pas connaître les classes qui en dérivent, sauf si elle est définie dans le même fichier. La meilleure façon de garantir que tous les modèles sont chargés, vous pouvez simplement appeler require sur tous les fichiers dans le répertoire app/models:

Dir.glob(RAILS_ROOT + '/app/models/*.rb').each { |file| require file } 

Une autre chose à noter est que la méthode subclasses ne fonctionne pas après avoir émis la commande reload! dans la console Rails.

+0

'Dir.glob (RAILS_ROOT + '/app/models/*.rb').each {| fichier | Le fichier require_dependency} 'peut fonctionner mieux et est plus rapide. Le rapper dans le bloc 'config.to_prepare {}' ou 'config.after_initialize {}' dans l'environnement est utile. – MegaTux

+0

Bon à savoir, merci. –

0

La raison pour laquelle vous obtenez un tableau vide dans Rails 3 est probablement due au fait que Rails 3 utilise le chargement automatique.

Si vous ouvrez la console Rails et que vous référencez le nom des sous-classes, exécutez la méthode 'subclasses' sur la classe parent, vous verrez que cela fonctionne. En effet, Rails 3 charge uniquement les classes dans la mémoire que vous avez référencée lorsque vous les référencez.

La façon dont je fini par forcer mes classes à charger à partir d'une bibliothèque que j'ai créé sous/lib était avec le code suivant j'ai ajouté dans la méthode qui dépend de ces classes:

# load feature subclasses 
my_classes_path = File.expand_path(File.dirname(__FILE__)) + "/my_classes" 
if File.directory?(my_classes_path) 
    Dir.glob(my_classes_path + "/*.rb").each do |f| 
    load f 
    end 
end 
Questions connexes