I have a Rails 2.2 project in which I want to override the functionality of the rake db:test:prepare
task. I thought this would work, but it doesn't:
#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
I get the standard task's behaviour. If I change the name of the task to :prepare2
and then do rake db:test:prepare2
, then it works fine. The natural conclusion I draw from this is that my rake tasks are being defined before the built-in Rails ones, so mine is overridden by the standard :prepare
task.
Can anyone see how I can fix this? I'd rather override it than have to use a new task. Thanks, max
Rake is a popular task runner for Ruby and Rails applications. For example, Rails provides the predefined Rake tasks for creating databases, running migrations, and performing tests. You can also create custom tasks to automate specific actions - run code analysis tools, backup databases, and so on.
Including => :environment will tell Rake to load full the application environment, giving the relevant task access to things like classes, helpers, etc. Without the :environment , you won't have access to any of those extras.
A Rakefile contains executable Ruby code. Anything legal in a ruby script is allowed in a Rakefile. Now that we understand there is no special syntax in a Rakefile, there are some conventions that are used in a Rakefile that are a little unusual in a typical Ruby program.
If you define a rake task that already exists, its execution gets appended to the original task's execution; both tasks will be executed.
If you want to redefine a task you need to clear the original task first:
Rake::Task["db:test:prepare"].clear
It's also useful to note that once a task has been executed in rake, it won't execute again even if you call it again. This is by design but you can call .reset
on a task to allow it to be run again.
You have to remove the default task before adding your own:
Rake.application.instance_variable_get('@tasks').delete('db:test:prepare') namespace 'db' do namespace 'test' do task 'prepare' do # ... end end end
A fairly popular idiom is to create a convenience method called remove_task
like so:
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
(Source: drnic/newgem
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With