2010-12-08 4 views
2

Lassen Sie uns sagen, dass ich etwas wie diesesUnterschiede in Unterklassen funktionieren zwischen Schienen 2 und 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 

In Rails 2.3 Ich konnte Major.my_kids rufen und wieder ein Array der Unterklasse Namen, aber in Rails 3.0. 3 Ich bekomme ein leeres Array zurück, es sei denn, ich lade zuerst die Unterklassen. Das scheint mir falsch, fehlt mir etwas oder ist das neu bei Rails 3?

Antwort

2

Es gibt keinen Unterschied, den ich zwischen Rails 2 und 3 über die Verwendung der subclasses Methode weiß. Sie haben vielleicht geglaubt, dass es vorher funktioniert hat, weil die Unterklassen bereits geladen waren. Da Rails die meisten Dateien dynamisch lädt, kann eine Elternklasse nichts über eine abgeleitete Klasse wissen, es sei denn, sie ist in derselben Datei definiert. Der einfachste Weg, alle Modelle, um sicherzustellen, geladen sind, können Sie einfach require auf alle Dateien im Verzeichnis app/models anrufen:

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

Eine andere Sache zu beachten ist, dass die subclasses Methode funktioniert nicht nach der Ausgabe des reload! Befehl in die Rails-Konsole.

+0

'Dir.glob (RAILS_ROOT + '/app/models/*.rb').each {| Datei | require_dependency file} 'funktioniert möglicherweise besser und ist schneller. Es ist nützlich in der '' config.to_prepare {} 'oder' config.after_initialize {} 'Block in der Umgebung zu rappen. – MegaTux

+0

Gut zu wissen, danke. –

0

Der Grund, warum Sie in Rails 3 ein leeres Array erhalten, liegt wahrscheinlich daran, dass Rails 3 Autoloading verwendet.

Wenn Sie die Rails-Konsole öffnen und auf den Namen der Unterklassen verweisen, führen Sie die Methode 'subclasses' für die Elternklasse aus. Sie werden sehen, dass sie funktioniert. Dies liegt daran, dass Rails 3 die Klassen nur in den Speicher lädt, auf den Sie verwiesen haben, wenn Sie auf sie verweisen.

Die Art, wie ich meine Klassen am Ende zwang aus einer Bibliothek zu laden Ich habe unter/lib mit dem folgenden Code war ich in das Verfahren aufgenommen, die auf diesen Klassen abhängt:

# 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 
Verwandte Themen