web-dev-qa-db-ja.com

Railsのデフォルトのrakeタスクをオーバーライドする

rake db:test:prepareタスクの機能をオーバーライドしたいRails 2.2プロジェクトがあります。これは機能すると思いましたが、機能しません:

#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

標準タスクの動作を取得します。タスクの名前を:prepare2に変更してからrake db:test:prepare2を実行すると、正常に機能します。私がこれから引き出す自然な結論は、私のrakeタスクが定義されているということですbeforeビルトインRails ones、だから私のものは標準の:prepareタスクによって上書きされます。

誰も私がこれを修正する方法を見ることができますか?新しいタスクを使用するよりも、むしろオーバーライドしたいです。ありがとう、max

70
Max Williams

既に存在するrakeタスクを定義すると、その実行は元のタスクの実行に追加されます。両方のタスクが実行されます。

タスクを再定義する場合は、最初に元のタスクをクリアする必要があります。

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

また、タスクがrakeで実行されると、再度呼び出しても再度実行されないことに注意してください。これは仕様によるものですが、.resetタスクの再実行を許可します。

121
Brendon Muir

独自のタスクを追加する前に、デフォルトのタスクを削除する必要があります。

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

かなり一般的なイディオム は、次のようなremove_taskという便利なメソッドを作成することです。

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

ソース:drnic/newgem

11
Alex Peattie

lib/tasks /に新しいproject.rakeファイルを作成し、その下にコードを貼り付けます。

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

Krasimir Angelovのブログに触発された

6
Eric Guo