覆盖Rails的默认rake任务


74

我有一个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

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

谁能看到我该如何解决?我宁愿重写它,也不必使用新任务。谢谢,最大


也许您可以直接在RAILS_ROOT中修改Rakefile?
圣诞老人张

Answers:


127

如果您定义了一个已经存在的rake任务,那么它的执行将被附加到原始任务的执行之后;这两个任务都将执行。

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

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

还需要注意的是,一旦在rake中执行了任务,即使再次调用它也不会再次执行。这是设计使然,但是您可以调用.reset任务以使其再次运行。


嗯,看起来也可以,并且语法更好。谢谢!
Max Williams

1
不用担心:)我想这可能是某人第一次接受我的回答!:D
布伦登·缪尔

12
如果所涉及的任务不存在(例如,如果您在生产与开发模式下运行),则此操作可能会失败。为了使该任务即使在不存在的任务下也能正常工作,请首先创建一个隐式的空任务:task :default => []; Rake::Task[:default].clear
Jo Liss 2012年

Rake :: Task.clear Rake :: Task ['rake_task']。reenable Rake :: Task ['rake_task']。invoke可以吗?
faisal bhatti

13

您必须先删除默认任务,然后再添加自己的任务:

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


1
谢谢亚历克斯(Alex),对我而言,最优秀的一个很好,而且为了其他人的关注,最显而易见的是发生了什么。干杯
马克斯·威廉斯

6

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博客的启发

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.