Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding rails' default rake tasks

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

like image 514
Max Williams Avatar asked Nov 13 '11 14:11

Max Williams


People also ask

What are Rake tasks in Rails?

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.

What is environment rake task?

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.

What is Rakefile?

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.


2 Answers

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.

like image 152
Brendon Muir Avatar answered Oct 11 '22 01:10

Brendon Muir


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)

like image 37
Alex Peattie Avatar answered Oct 11 '22 00:10

Alex Peattie