web-dev-qa-db-fra.com

Remplacement des tâches de râteau par défaut de Rails

J'ai un projet Rails 2.2 dans lequel je souhaite remplacer la fonctionnalité du rake db:test:prepare tâche. Je pensais que cela fonctionnerait, mais cela ne fonctionne pas:

#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

J'obtiens le comportement de la tâche standard. Si je change le nom de la tâche en :prepare2 puis faites rake db:test:prepare2, alors ça marche bien. La conclusion naturelle que j'en tire est que mes tâches de râteau sont définies avant celles intégrées Rails celles, donc la mienne est remplacée par la norme :prepare tâche.

Quelqu'un peut-il voir comment je peux résoudre ce problème? Je préfère le remplacer plutôt que d'avoir à utiliser une nouvelle tâche. Merci, max

70
Max Williams

Si vous définissez une tâche de râteau qui existe déjà, son exécution est ajoutée à l'exécution de la tâche d'origine; les deux tâches seront exécutées.

Si vous souhaitez redéfinir une tâche, vous devez d'abord effacer la tâche d'origine:

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

Il est également utile de noter qu'une fois qu'une tâche a été exécutée en râteau, elle ne s'exécutera plus, même si vous la rappelez. C'est par conception mais vous pouvez appeler .reset sur une tâche pour lui permettre de s'exécuter à nouveau.

121
Brendon Muir

Vous devez supprimer la tâche par défaut avant d'ajouter la vôtre:

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

Un idiome assez populaire consiste à créer une méthode pratique appelée remove_task ainsi:

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

( La source: drnic/newgem )

11
Alex Peattie

Créez un nouveau fichier project.rake dans lib/tasks/, et passez-y le code ci-dessous.

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']

inspiré par le blog de Krasimir Angelov

6
Eric Guo