我有一个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任务,因此我的标准:prepare
任务会覆盖我的。{/ p>
答案 0 :(得分:118)
如果您定义了一个已经存在的rake任务,它的执行将被附加到原始任务的执行中;这两项任务都将被执行。
如果要重新定义任务,则需要先清除原始任务:
Rake::Task["db:test:prepare"].clear
注意一旦任务在rake中执行,即使再次调用它也不会再次执行,这也很有用。这是设计使然,但您可以在任务上调用.reset
以允许它再次运行。
答案 1 :(得分:11)
在添加自己的任务之前,您必须删除默认任务:
Rake.application.instance_variable_get('@tasks').delete('db:test:prepare')
namespace 'db' do
namespace 'test' do
task 'prepare' do
# ...
end
end
end
fairly popular idiom是创建一个名为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
答案 2 :(得分: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']
的启发