Ich schreibe einen benutzerdefinierten Wrapper für das open_flash_chart
Plugin. Es wird platziert /lib
und als Modul geladen ApplicationController
.
Ich habe jedoch ein Klassenhierarchie- oder SMTH-Problem.
Von jedem Controller kann ich Zugriff auf open_flash_chart
Funktionen wie OpenFlashChart
, Line
etc
In einer Klasse in einem /lib
Modul funktioniert es jedoch nicht!
Irgendwelche Ideen?
ruby-on-rails
ruby
class
module
Mantas
quelle
quelle
Antworten:
Es gibt zwei Möglichkeiten, wie Dateien in Rails geladen werden:
app/controllers/pages_controller.rb
PagesController haben und darauf verweisen,app/controllers/pages_controller.rb
wird dieser automatisch geladen. Dies geschieht für eine voreingestellte Liste von Verzeichnissen im Ladepfad. Dies ist eine Funktion von Rails und nicht Teil des normalen Ruby-Ladevorgangs.require
d. Wenn eine Dateirequire
d ist, durchsucht Ruby die gesamte Liste der Pfade in Ihren Ladepfaden und findet den ersten Fall, in dem sich die Dateirequire
d im Ladepfad befindet. Sie können den gesamten Ladepfad anzeigen, indem Sie $ LOAD_PATH (ein Alias für $ :) überprüfen.Da
lib
sich in Ihrem Ladepfad zwei Optionen befinden: Sie können Ihre Dateien entweder mit denselben Namen wie die Konstanten benennen, sodass Rails sie automatisch aufnimmt, wenn Sie auf die betreffende Konstante verweisen, oder das Modul explizit anfordern.Ich bemerke auch, dass Sie über eine andere Sache verwirrt sein könnten. ApplicationController ist nicht das Stammobjekt im System. Beobachten:
Sie müssen das Modul in jede Klasse aufnehmen, in der Sie es verwenden möchten.
Um das Modul überhaupt einbinden zu können, muss es natürlich verfügbar sein (mit einer der oben genannten Techniken).
quelle
In Rails 3 / lib werden Module nicht automatisch geladen.
Dies liegt daran, dass die Zeile:
in config / application.rb wird kommentiert.
Sie können versuchen, diese Zeile zu kommentieren oder (für mich hat es noch besser funktioniert) diesen Kommentar zu hinterlassen (zum späteren Nachschlagen) und diese beiden Zeilen hinzufügen:
quelle
../lib
Pfad imApplicationName::Application.config.autoload_paths
Array dupliziert .config.autoload_paths += Dir["#{config.root}/lib/**/"]
sollte reichen. @ckarbass In der zweiten Zeile haben Sie die Freiheit, Ihre Dienstprogramme in Unterordnern zu organisieren und so Ihre Module mit Namespaces zu versehen . Das wars so ziemlich. Und hier ist, warum die Standardeinstellung geändert wurde. Besser spät als nie :)Neben dem Auskommentieren von config.autoload_paths (I'm on Rails 3.1.3) funktionierte für mich die Erstellung eines Initialisierers wie folgt:
Auf diese Weise kann ich mymodule-Methoden von überall und als Klassenmethoden
Model.mymodule_method
oder als Instanzmethoden aufrufenmymodel.mymodule_method
Vielleicht kann ein Experte die Auswirkungen erklären. Verwenden Sie es jetzt auf eigenes Risiko.
Edit: Danach denke ich, ein besserer Ansatz wäre:
Erstellen Sie einen Initialisierer wie folgt:
Fügen Sie das Modul bei Bedarf wie folgt hinzu:
1) Wenn Sie es als "Klassenmethoden" verwenden möchten, verwenden Sie "Erweitern":
2) Wenn Sie es als "Instanzmethoden" verwenden möchten, fügen Sie es in die Klassendefinition ein:
3) Denken Sie daran, dass
include MyModule
sich dies auf eine Dateimy_module.rb
in Ihrem Ladepfad bezieht, die zuerst benötigt werden mussquelle
lib
Ordner, also ich habe hinzugefügtconfig.autoload_paths += %W(#{config.root}/lib)
aufconfig/application.rb
Datei. Danach folgte ich Ihrem Vorschlag, eineconfig/initializers/myapp_init.rb
Datei und deren Inhalt hinzuzufügen . Alles ist gut. Vielen Dank :)require
für mich funktioniert und das automatische Laden nicht funktioniert (undefinierte Modulmethode), heißt es in diesem Kommentar, dass Sie es nicht verwenden solltenrequire
.So verwenden Sie das Modul
lib/my_module.rb
in Ihren Modellen und Steuerungen:In
config/application.rb
:In Ihrem Modell (ähnliche Idee für Ihren Controller):
Diese Methode wird unter http://hakunin.com/rails3-load-paths ausführlicher beschrieben
quelle
Möglicherweise möchten Sie zum Zeitpunkt der Anwendungsinitialisierung Dateien explizit im Verzeichnis lib laden.
In meiner config / application.rb habe ich einen Eintrag als.
config.autoload_paths += %W(#{config.root}/lib)
Dies kann auch der Fall sein, dass der Name / die Hierarchie des Moduls nicht mit dem in der Datei übereinstimmt oder dass der Speicherort / Name der Datei nicht mit dieser Hierarchie übereinstimmt. Laden Sie sie daher automatisch dieser Datei ist auch nicht möglich. Als ich also unten in config / application.rb as einen Eintrag hinzufügte,
require "./lib/file_name_without_extention
funktionierte das einwandfrei.
quelle