it-swarm.com.de

Automatisches Laden von lib-Dateien in Rails 4

In einem Initialisierer verwende ich die folgende Zeile, um während der Entwicklung den Code in meinem /lib - Verzeichnis automatisch zu laden:

config/initializers/custom.rb:

RELOAD_LIBS = Dir[Rails.root + 'lib/**/*.rb'] if Rails.env.development?

(von Rails 3 Quicktip: Lib-Ordner im Entwicklungsmodus automatisch neu laden )

Es funktioniert prima, ist aber zu ineffizient, um in der Produktion verwendet zu werden. Anstatt die Bibliotheken bei jeder Anforderung zu laden, möchte ich sie nur beim Start laden. Das gleiche Blog hat ein anderer Artikel beschreibt, 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 selbst in der Entwicklung darauf umsteige, 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

Durch Aufrufen von Time.milli_stamp Wird NoMethodError ausgelöst

Mir ist klar, dass andere ähnliche Fragen zu SO) beantwortet haben, aber sie scheinen sich alle mit Namenskonventionen und anderen Problemen zu befassen, über die ich mir vorher keine Sorgen machen musste - Meine Bibliotheksklassen bereits funktioniert für das Laden pro Anfrage, ich möchte es nur per ändern - Start Laden. Was ist der richtige Weg, um dies zu tun?

225
Yarin

Ich denke, das könnte Ihr Problem lösen:

  1. in config/application.rb :

    config.autoload_paths << Rails.root.join('lib')
    

    und behalte die richtige Namenskonvention in lib .

    in lib/foo.rb :

    class Foo
    end
    

    in lib/foo/bar.rb :

    class Foo::Bar
    end
    
  2. wenn Sie wirklich einige Affen-Patches in einer Datei wie lib/extensions.rb ausführen möchten, können Sie dies manuell anfordern:

    in config/initializers/require.rb :

    require "#{Rails.root}/lib/extensions" 
    

P.S

545
ifyouseewendy

Dies beantwortet zwar nicht direkt die Frage, aber ich denke, es ist eine gute Alternative, die Frage insgesamt zu vermeiden.

Um alle autoload_paths oder eager_load_paths Ärger, erstelle ein "lib" - oder ein "misc" -Verzeichnis unter "app" -Verzeichnis. Platzieren Sie die Codes wie gewohnt, und Rails) lädt die Dateien genauso wie die Modelldateien (und lädt sie neu).

33
lulalala

Dies könnte jemandem wie mir helfen, der diese Antwort findet, wenn er nach Lösungen sucht, wie Rails behandelt das Laden der Klasse ... Ich stellte fest, dass ich ein module definieren musste, dessen Name übereinstimmte Mein Dateiname passt, anstatt nur eine Klasse zu definieren:

In der Datei lib/development_mail_interceptor.rb (Ja, ich verwende Code aus einem Railscast :))

module DevelopmentMailInterceptor
  class DevelopmentMailInterceptor
    def self.delivering_email(message)
      message.subject = "intercepted for: #{message.to} #{message.subject}"
      message.to = "[email protected]"
    end
  end
end

funktioniert, wird aber nicht geladen, wenn ich die Klasse nicht in ein Modul eingefügt hätte.

6
sameers

Verwenden Sie config.to_prepare, um Affen-Patches/-Erweiterungen für jede Anforderung im Entwicklungsmodus zu laden.

config.to_prepare do |action_dispatcher|
 # More importantly, will run upon every request in development, but only once (during boot-up) in production and test.
 Rails.logger.info "\n--- Loading extensions for #{self.class} "
 Dir.glob("#{Rails.root}/lib/extensions/**/*.rb").sort.each do |entry|
   Rails.logger.info "Loading extension(s): #{entry}"
   require_dependency "#{entry}"
 end
 Rails.logger.info "--- Loaded extensions for #{self.class}\n"

ende

0
Madx