Da die neueste Version von Rails 3 keine Module und Klassen mehr automatisch aus lib lädt, wie lassen Sie sie am besten laden?
Vom Github:
A few changes were done in this commit: Do not autoload code in *lib* for applications (now you need to explicitly require them). This makes an application behave closer to an engine (code in lib is still autoloaded for plugins);
app/lib
.Quelle: Rails 3 Quicktip: Autoload lib-Verzeichnis einschließlich aller Unterverzeichnisse. Vermeiden Sie verzögertes Laden
Bitte beachten Sie, dass die im lib-Ordner enthaltenen Dateien nur beim Starten des Servers geladen werden. Wenn Sie möchten, dass diese Dateien bequem automatisch geladen werden, lesen Sie: Rails 3 Quicktip: Lib-Ordner im Entwicklungsmodus automatisch neu laden . Beachten Sie, dass dies nicht für eine Produktionsumgebung gedacht ist, da das permanente Nachladen die Maschine verlangsamt.
quelle
Die Magie des automatischen Ladens von Sachen
Ich denke, die Option, die Ordner zu steuern, aus denen das automatische Laden durchgeführt wird, wurde in anderen Antworten ausreichend behandelt. Falls jedoch jemand anderes Probleme beim Laden hat, obwohl die Autoload-Pfade nach Bedarf geändert wurden, versucht diese Antwort zu erklären, was die Magie hinter diesem Autoload-Ding ist.
Wenn es darum geht, Inhalte aus Unterverzeichnissen zu laden, gibt es eine Gotcha oder eine Konvention, die Sie beachten sollten. Manchmal kann die Ruby / Rails-Magie (diesmal meistens Rails) es schwierig machen zu verstehen, warum etwas passiert. Jedes in den Autoload-Pfaden deklarierte Modul wird nur geladen, wenn der Modulname dem Namen des übergeordneten Verzeichnisses entspricht. Für den Fall, dass Sie versuchen,
lib/my_stuff/bar.rb
etwas zu tun wie:Es wird nicht automatisch geladen. Wenn Sie das übergeordnete Verzeichnis
foo
so umbenennen, dass Ihr Modul unter folgendem Pfad gehostet wird :lib/foo/bar.rb
. Es wird für Sie da sein. Eine andere Möglichkeit besteht darin, die Datei, die automatisch geladen werden soll, anhand des Modulnamens zu benennen. Offensichtlich kann es dann nur eine Datei mit diesem Namen geben. Falls Sie Ihre Daten in viele Dateien aufteilen müssen, können Sie diese eine Datei natürlich verwenden, um andere Dateien zu benötigen. Ich empfehle dies jedoch nicht, da Rails im Entwicklungsmodus und wenn Sie diese anderen Dateien ändern, nicht in der Lage ist, automatisch zu arbeiten lade sie für dich neu. Wenn Sie jedoch wirklich möchten, können Sie eine Datei mit dem Modulnamen haben, die dann die tatsächlichen Dateien angibt, die für die Verwendung des Moduls erforderlich sind. Sie könnten also zwei Dateien haben:lib/my_stuff/bar.rb
undlib/my_stuff/foo.rb
die erste ist dieselbe wie oben und die zweite enthält eine einzelne Zeile:require "bar"
und das würde genauso funktionieren.PS Ich fühle mich gezwungen, noch eine wichtige Sache hinzuzufügen. Wenn ich in letzter Zeit etwas im lib-Verzeichnis haben möchte, das automatisch geladen werden muss, neige ich dazu zu denken, dass es eines Tages etwas sein könnte, das ich speziell für dieses Projekt entwickle (was es normalerweise ist) verwandeln Sie sich in einen "statischen" Codeausschnitt, der in vielen Projekten oder in einem Git-Submodul usw. verwendet wird. In diesem Fall sollte er sich definitiv im lib-Ordner befinden. Dann befindet sich sein Platz möglicherweise überhaupt nicht im lib-Ordner. Vielleicht sollte es sich in einem Unterordner unter dem App-Ordner befinden. · Ich habe das Gefühl, dass dies die neue Art und Weise ist, Dinge zu tun. Offensichtlich ist die gleiche Magie überall dort wirksam, wo Sie in Ihren Autoload-Pfaden Ihre Sachen ablegen, damit es gut für diese Dinge ist. Jedenfalls sind dies nur meine Gedanken zu diesem Thema. Es steht Ihnen frei, anderer Meinung zu sein. :) :)
UPDATE: Über die Art der Magie ..
Wie Severin in seinem Kommentar betonte, ist der Kern "Autoload a Module Mechanism" sicher ein Teil von Ruby, aber das Autoload Paths-Zeug ist es nicht. Sie brauchen keine Rails zu tun
autoload :Foo, File.join(Rails.root, "lib", "my_stuff", "bar")
. Und wenn Sie zum ersten Mal versuchen würden, auf das Modul Foo zu verweisen, wird es für Sie geladen. Rails bietet uns jedoch die Möglichkeit, Inhalte automatisch aus registrierten Ordnern zu laden. Dies wurde so implementiert, dass etwas über die Namenskonventionen vorausgesetzt werden muss. Wenn es nicht so implementiert worden wäre, müsste es jedes Mal, wenn Sie auf etwas verweisen, das gerade nicht geladen ist, alle Dateien in allen Autoload-Ordnern durchsuchen und prüfen, ob eine von ihnen das enthält, worauf Sie verweisen wollten. Dies würde wiederum die Idee des automatischen Ladens und automatischen Ladens zunichte machen. Mit diesen Konventionen kann es jedoch von dem Modul / der Klasse abziehen, dass Sie versuchen, dort zu laden, wo dies definiert sein könnte, und dies einfach laden.quelle
Warnung: Wenn Sie den 'Monkey Patch' oder die 'Open Class' aus Ihrem 'lib'-Ordner laden möchten, verwenden Sie nicht den ' Autoload'-Ansatz !!!
Ansatz " config.autoload_paths ": Funktioniert nur, wenn Sie eine Klasse laden, die nur an EINER Stelle definiert ist. Wenn eine Klasse bereits an einer anderen Stelle definiert wurde, können Sie sie mit diesem Ansatz nicht erneut laden.
Ansatz " config / initializer / load_rb_file.rb ": funktioniert immer! Was auch immer die Zielklasse eine neue Klasse oder eine "offene Klasse" oder ein "Affen-Patch" für eine vorhandene Klasse ist, es funktioniert immer!
Weitere Informationen finden Sie unter: https://stackoverflow.com/a/6797707/445908
quelle
Sehr ähnlich, aber ich finde das etwas eleganter:
quelle
In meinem Fall habe ich versucht, einfach eine Datei direkt unter das lib-Verzeichnis zu laden.
Innerhalb von application.rb ...
funktionierte nicht, auch nicht in der Konsole und dann, als ich es versuchte
und Rails lädt die Datei perfekt.
Ich bin immer noch ziemlich noob und ich bin nicht sicher, warum das funktioniert, aber es funktioniert. Wenn jemand es mir erklären möchte, würde ich es begrüßen: DI hoffe, das hilft jemandem so oder so.
quelle
Ich hatte das gleiche Problem. Hier ist, wie ich es gelöst habe. Die Lösung lädt das lib-Verzeichnis und alle Unterverzeichnisse (nicht nur das direkte). Natürlich können Sie dies für alle Verzeichnisse verwenden.
quelle
Expected lib/bar/foo.rb to define constant Foo
angezeigt , z. B. wenn Sie versuchen, lib / foo.rb zu laden, indem Sie sich auf Foo beziehen Konstante.config.autoload_paths funktioniert bei mir nicht. Ich löse es auf andere Weise
quelle
Wenn nur bestimmte Dateien Zugriff auf die Module in lib benötigen, fügen Sie einfach eine require-Anweisung zu den Dateien hinzu, die sie benötigen. Wenn beispielsweise ein Modell auf ein Modul zugreifen muss, fügen Sie Folgendes hinzu:
oben in der Datei model.rb.
quelle
require
in einer Rails-App verwenden, da dies verhindert,ActiveSupport::Dependencies
dass der Code ordnungsgemäß [ent] geladen wird. Stattdessen sollten Sieconfig.autoload_paths
wie die obige Antwort verwenden und dann nach Bedarf einschließen / erweitern.require
von irgendwo in einer Rails-App? In einer Harke Aufgabe bin ich zur Zeitrequire
-ing undinclude
-ing ein Modul , das in lebtlib/
. Sollte ich das nicht tun?require
Ihremlib/
Code gemeinsam ist (z. B. dieser Blog-Beitrag , diese SO-Antwort ). Ich bin mir immer noch nicht sicher. Können Sie mehr Beweise für die Behauptung liefern, dass Sie nicht verwendet habenrequire
?Schreiben Sie den Dateinamen richtig.
Ernsthaft. Ich habe eine Stunde lang mit einer Klasse gekämpft, weil die Klasse Governance :: ArchitectureBoard war und sich die Datei in lib / Governance / Architecture_baord.rb befand (transponierte O und A in "board").
Scheint im Nachhinein offensichtlich, aber es war der Teufel, der das aufspürte. Wenn die Klasse nicht in der Datei definiert ist, in der Rails sie erwartet, basierend auf dem Munging des Klassennamens, wird sie sie einfach nicht finden.
quelle
Ab
Rails 5
, wird empfohlen , den Ordner lib unter App - Verzeichnis zu setzen oder stattdessen erstellen andere sinnvolle Namensräume für den Ordner wieservices
,presenters
,features
usw. und es für die automatische Beladung von Schienen unter App Verzeichnis.Bitte überprüfen Sie auch diesen GitHub-Diskussionslink .
quelle
Es gibt mehrere Gründe, warum Sie Probleme beim Laden aus lib haben könnten - siehe hier für Details - http://www.williambharding.com/blog/technology/rails-3-autoload-modules-and-classes-in-production/
quelle