Überschreiben der Standardrechenaufgaben der Schienen

74

Ich habe ein Rails 2.2-Projekt, in dem ich die Funktionalität der rake db:test:prepareAufgabe überschreiben möchte . Ich dachte, das würde funktionieren, aber es funktioniert nicht:

#lib/tasks/db.rake
namespace :db do
  namespace :test do
    desc "Overridden version of rails' standard db:test:prepare task since the schema dump used in that can't handle DB enums"  
    task :prepare => [:environment] do
      puts "doing db:structure:dump"
      Rake::Task['db:structure:dump'].invoke
      puts "doing db:test:clone_structure"
      Rake::Task['db:test:clone_structure'].invoke
    end   
  end
end

Ich bekomme das Verhalten der Standardaufgabe. Wenn ich den Namen der Aufgabe in ändere :prepare2und dann tue rake db:test:prepare2, funktioniert es einwandfrei. Die natürliche Schlussfolgerung, die ich daraus ziehe, ist, dass meine Rake-Aufgaben vor den integrierten Rails- Aufgaben definiert werden, sodass meine Aufgaben von der Standardaufgabe überschrieben werden :prepare.

Kann jemand sehen, wie ich das beheben kann? Ich würde es lieber überschreiben, als eine neue Aufgabe verwenden zu müssen. Danke, max

Max Williams
quelle
Vielleicht können Sie das Rakefile in RAILS_ROOT direkt ändern?
Santa Zhang

Antworten:

127

Wenn Sie eine bereits vorhandene Rake-Task definieren, wird ihre Ausführung an die Ausführung der ursprünglichen Task angehängt. Beide Aufgaben werden ausgeführt.

Wenn Sie eine Aufgabe neu definieren möchten, müssen Sie zuerst die ursprüngliche Aufgabe löschen:

Rake::Task["db:test:prepare"].clear

Es ist auch nützlich zu beachten, dass eine einmal ausgeführte Aufgabe in Rake nicht erneut ausgeführt wird, selbst wenn Sie sie erneut aufrufen. Dies ist beabsichtigt, aber Sie können .reseteine Aufgabe aufrufen , damit sie erneut ausgeführt werden kann.

Brendon Muir
quelle
Ah, sieht so aus, als würde das auch funktionieren und ist eine viel schönere Syntax. Vielen Dank!
Max Williams
1
Keine Sorge :) Ich denke, das ist vielleicht das erste Mal, dass jemand eine Antwort von mir akzeptiert! : D
Brendon Muir
12
Dies kann fehlschlagen, wenn die betreffende Aufgabe nicht vorhanden ist (z. B. wenn Sie in einem Produktions- oder Entwicklungsmodus ausgeführt werden). Damit es auch dann funktioniert, wenn die Aufgabe nicht vorhanden ist, erstellen Sie zuerst eine implizite leere Aufgabe:task :default => []; Rake::Task[:default].clear
Jo Liss
Rake :: Task.clear Rake :: Task ['rake_task']. Rake :: Task ['rake_task'] wieder aktivieren. Invoke Ist das in Ordnung?
Faisal Bhatti
13

Sie müssen die Standardaufgabe entfernen, bevor Sie Ihre eigene hinzufügen können:

Rake.application.instance_variable_get('@tasks').delete('db:test:prepare')
namespace 'db' do
  namespace 'test' do
    task 'prepare' do
      # ...
    end
  end
end

Eine ziemlich beliebte Redewendung ist es, eine Convenience-Methode zu erstellen, die remove_taskwie folgt heißt :

Rake::TaskManager.class_eval do
  def remove_task(task_name)
    @tasks.delete(task_name.to_s)
  end
end

def remove_task(task_name)
  Rake.application.remove_task(task_name)
end

( Quelle:drnic/newgem )

Alex Peattie
quelle
1
Danke Alex, das Top ist in Ordnung für mich und auch offensichtlicher, was los ist, für alle anderen, die es sich ansehen. Prost
Max Williams
6

Erstellen Sie eine neue project.rake- Datei unter lib / task / und geben Sie den folgenden Code ein.

namespace :mv do
desc "Display hint and info for your rails 4 project"
task info: :environment do
    puts 'Run rake test to test'
end
end

task(:default).clear.enhance ['mv:info']

inspiriert von Krasimir Angelovs Blog

Eric Guo
quelle