Ich verwende die folgende Zeile in einem Initialisierer, um Code in meinem /lib
Verzeichnis während der Entwicklung automatisch zu laden :
config / initializers / custom.rb:
RELOAD_LIBS = Dir[Rails.root + 'lib/**/*.rb'] if Rails.env.development?
(aus Rails 3 Quicktip: Lib-Ordner im Entwicklungsmodus automatisch neu laden )
Es funktioniert gut, ist aber zu ineffizient, um es in der Produktion zu verwenden. Anstatt bei jeder Anforderung Bibliotheken zu laden, möchte ich sie nur beim Start laden. Im selben Blog gibt es einen weiteren Artikel, in dem beschrieben wird, wie das geht:
config / application.rb:
# Custom directories with classes and modules you want to be autoloadable.
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
Wenn ich jedoch auch in der Entwicklung dazu wechsle, erhalte ich NoMethodErrors, wenn ich versuche, die lib-Funktionen zu verwenden.
Beispiel einer meiner lib-Dateien:
lib / extensions.rb:
Time.class_eval do
def self.milli_stamp
Time.now.strftime('%Y%m%d%H%M%S%L').to_i
end
end
Beim Aufruf Time.milli_stamp
wird NoMethodError ausgelöst
Mir ist klar, dass andere ähnliche Fragen zu SO beantwortet haben, aber alle scheinen sich mit Namenskonventionen und anderen Problemen zu befassen, über die ich mir vorher keine Sorgen machen musste. Meine lib-Klassen haben bereits für das Laden pro Anfrage funktioniert , ich möchte sie nur ändern zum Laden pro Start . Was ist der richtige Weg, um dies zu tun?
Antworten:
Ich denke, das könnte Ihr Problem lösen:
in config / application.rb :
und halten Sie die richtige Namenskonvention in lib .
in lib / foo.rb :
in lib / foo / bar.rb :
Wenn Sie wirklich einige Affen-Patches in einer Datei wie lib / extensions.rb erstellen möchten , benötigen Sie diese möglicherweise manuell:
in config / initializers / require.rb :
PS
Schienen 3 Autoload-Module / Klassen von Bill Harding.
Und um zu verstehen, was Rails genau gegen das automatische Laden tut?
Lesen Sie Rails Autoloading - wie es funktioniert und wann nicht von Simon Coffey.
quelle
config.eager_load_paths << Rails.root.join('lib')
. Dies hat jedoch einen großen Nachteil darin, dass aucheager_load_paths
bei Aufgaben alles geladen wird. Ich denke, dass die Lösung von Lulalala besser ist. Hier ist ein Blog-Beitrag mit weiteren Details: blog.arkency.com/2014/11/…Dies beantwortet zwar nicht direkt die Frage, aber ich denke, es ist eine gute Alternative, um die Frage insgesamt zu vermeiden.
Um all das
autoload_paths
odereager_load_paths
Ärger zu vermeiden , erstellen Sie ein "lib" - oder ein "misc" -Verzeichnis unter "app" -Verzeichnis. Platzieren Sie Codes wie gewohnt dort, und Rails lädt Dateien genauso wie Modelldateien (und lädt sie neu).quelle
app
, ich muss es manuell tun ...... oder muss es in den Autload-Pfad setzen ..app/views
Verzeichnisses, das nicht hinzugefügt wird; oder vielmehr wird explizit entfernt.lib
dies für Code gedacht ist, der auf mehrere Projekte angewendet und möglicherweise in ein Juwel extrahiert werden kann. Wenn nicht, erstellen Sie unter App-Suche einen passenderen Ordner alsservices/
oderpresenters/
und unterschreiben Sie diese sogar.Dies könnte jemandem wie mir helfen, der diese Antwort findet, wenn er nach Lösungen sucht, wie Rails mit dem Laden von Klassen umgeht ... Ich stellte fest, dass ich eine definieren musste
module
dessen Name meinem Dateinamen angemessen entspricht, anstatt nur eine Klasse zu definieren:In der Datei lib / development_mail_interceptor.rb (Ja, ich verwende Code aus einem Railscast :))
funktioniert, wird aber nicht geladen, wenn ich die Klasse nicht in ein Modul eingefügt habe.
quelle
LOAD_PATH/module/class.rb
(unterstrichen) befindet, wo sieLOAD_PATH
sich in den von der Ruby-App verwendeten Ladepfaden befindet (autoload_paths im Fall von Rails).lib
hat sich vom automatischen Laden durch Rails zum nicht automatischen Laden verändert und wird in neueren Versionen (> = Rails 3.x) nicht automatisch geladen. Was auch immer Magie diese Arbeit für Sie macht, wird nicht empfohlen. Vielleicht ist es ein alter Railscast?Verwenden Sie config.to_prepare, um Ihre Affen-Patches / -Erweiterungen für jede Anforderung im Entwicklungsmodus zu laden.
Ende
quelle