覆盖rails的默认rake任务

Max*_*ams 71 rake ruby-on-rails

我有一个Rails 2.2项目,我想在其中覆盖rake db:test:prepare任务的功能.我认为这会起作用,但它没有:

#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
Run Code Online (Sandbox Code Playgroud)

我得到了标准任务的行为.如果我将任务的名称更改为:prepare2然后执行rake db:test:prepare2,那么它可以正常工作.我从中得出的自然结论是,我的rake任务在内置的Rails 之前被定义,因此我的标准:prepare任务会覆盖我的rake 任务.

任何人都可以看到我如何解决这个问题?我宁愿覆盖它而不是使用新任务.谢谢,最多

Bre*_*uir 122

如果定义已存在的rake任务,则会将其执行附加到原始任务的执行中; 这两项任务都将被执行.

如果要重新定义任务,则需要先清除原始任务:

Rake::Task["db:test:prepare"].clear
Run Code Online (Sandbox Code Playgroud)

注意一旦任务在rake中执行,即使再次调用它也不会再次执行,这也很有用.这是设计的,但您可以调用.reset任务以允许它再次运行.

  • 如果相关任务不存在(例如,如果您在生产与开发模式下运行),则可能会失败.为了使它在任务不存在时工作,首先创建一个隐式空任务:`task:default => []; 耙::任务[:默认] .clear` (12认同)

Ale*_*tie 11

在添加自己的任务之前,您必须删除默认任务:

Rake.application.instance_variable_get('@tasks').delete('db:test:prepare')
namespace 'db' do
  namespace 'test' do
    task 'prepare' do
      # ...
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

一个相当流行的习语是创建一个方便的方法,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
Run Code Online (Sandbox Code Playgroud)

(来源:drnic/newgem)


Eri*_*Guo 6

lib/tasks /上创建一个新的project.rake文件,然后在代码中输入paster.

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']
Run Code Online (Sandbox Code Playgroud)

灵感来自Krasimir Angelov的博客