2012-11-13 8 views
6

Ich möchte meinen Cache mit einem Initialisierer auffüllen, aber ich brauche diesen Code nicht jedes Mal, wenn ich rake oder rails g usw. ausführe. Rake und Bundler sind einfach zu behandeln, aber eine ähnliche Lösung funktioniert nicht für die Generatoren:Wie verhindert werden, dass Initialisierungen ausgeführt werden, wenn "rails generate" ausgeführt wird

# config/initializers/prepop_cache.rb 
if !defined?(::Bundler) and !defined?(::Rake) and !defined(Rails::Generators) 
    # do stuff 
end 

Das muss sein, weil rails/generators (oder so ähnlich) ist require ed zur Laufzeit. Wie kann ich überprüfen, ob der ausgeführte Befehl rails g xyz ist?

Update:

Zwei Lösungen finden Sie hier: Rails 3 initializers that run only on `rails server` and not `rails generate`, etc

Noch würde gerne wissen, ob es in der Art und Weise möglich ist, die ich oben versucht habe.

Antwort

1

In Rails 3, was Sie suchen, ist denkbar, aber auf eine hacky Weise. Hier ist, wie:

Wenn Sie einen rails generate Anruf, sieht die CALLPATH wie folgt aus:

Innerhalb rails/commands der Code, der für erzeugen läuft:

ARGV << '--help' if ARGV.empty? 

aliases = { 
    "g" => "generate", 
    "c" => "console", 
    "s" => "server", 
    "db" => "dbconsole" 
} 

command = ARGV.shift      # <= #1 
command = aliases[command] || command 

case command 
when 'generate', 'destroy', 'plugin', 'benchmarker', 'profiler' 
    require APP_PATH 
    Rails.application.require_environment! # <= #2 
    require "rails/commands/#{command}"  # <= #3 

Die Sehenswürdigkeiten sind oben nummeriert. Nämlich, dass bei Punkt #1 der Befehl, den Sie ausführen, von ARGV verschiebt. Was in Ihrem Fall bedeutet, dass generate aus den Befehlszeilenargumenten entfernt wird.

Bei Punkt #2 wird Ihre Umgebung geladen, und an diesem Punkt werden Ihre Initialisierer ausgeführt. Und hier ist der schwierige Teil - da zu diesem Zeitpunkt noch nichts angegeben wurde, das einen bestimmten Befehl anzeigt (dies tritt bei #3 auf), gibt es keine Information, um festzustellen, dass ein Generator läuft!

Lasst uns ein Skript in config/initializer/debug.rb einfügen, um zu sehen, was verfügbar ist, wenn wir rails generate model meep lief:

puts $0  #=> "script/rails" 
puts ARGV #=> ["model", "meep"] 

Wie Sie sehen können, gibt es keine direkte Information, dass ein Generator ausgeführt wird. Das heißt, es gibt indirekte Informationen. Nämlich ARGV[0] #=> "model". Möglicherweise könnten Sie eine Liste möglicher Generatoren erstellen und überprüfen, ob dieser Generator unter ARGV[0] aufgerufen wurde. Der verantwortliche Entwickler in mir sagt, dass dies ein Hack ist und vielleicht auf eine Weise einbricht, die man nicht erwarten würde, also würde ich das vorsichtig verwenden.

Die einzige andere Möglichkeit ist, script/rails wie Sie vorgeschlagen zu ändern - das ist keine schlechte Lösung, aber würde wahrscheinlich brechen, wenn Sie auf Rails 4 aktualisieren.


In Rails 4, haben Sie mehr Hoffnung bekommen! Zu der Zeit application environment is being loaded wurde der Namespace des Generators bereits geladen. Dies bedeutet, dass Sie in einem Initialisierer Folgendes tun könnten:

if defined? Rails::Generators #=> "constant" 
    # code to run if generators loaded 
else 
    # code to run if generators not loaded 
end 
Verwandte Themen