#66 Custom Rake Tasks
Aug 13, 2007 | 10 minutes | Tools
Rake is one of those tools that you don't realize how powerful it is until you start using it. In this episode you will learn how to create custom rake tasks and improve them by using rake features.
So sweet, I was just about to write some custom rake tasks. Thanks Ryan. This is not the first time that you've published a screencast on a topic that i'm working on. Thanks once again.
Great!
I like the ":environment" to uses AR.
task :winner => :environment do
end
Great railscast Ryan. I miss the 3 per week fix I used to get, but still enjoy them one at a time.
Is there a way to programatically issue a rake command in a live application? There are times when I think it would be a good idea to have users invoke a generator or a rake task.
Thanks,
Bryce
@Bryce, good question. I don't know of a way to do this but I haven't looked into it much. If you are the author of the rake task, I recommend turning it into a class and putting it in your lib directory. Then you can use that class from both your rake task and anywhere else.
If anyone else knows a solution to this problem, please comment.
@Bryce, I think Ryan's suggestion of dropping it into a class is the best idea. Otherwise, you make something like a
system "cd #{RAILS_ROOT}; rake whatever"
though
system 'rake whatever'
might be sufficient.
That has its own problems, since it will block the entire request until that is done. An alternative would be using something like BackgroundRB or AP4R, and both requires you to run an additional server in the background.
Ho-Sheng Hsiao
Isshen, LLC
Thank you Ryan and Ho-Sheng. If I create a class, can Rails generate new files like a generator or rake task can? (should this go to the rails forum?)
The goal is to create db tables and .rhtml files programatically on the fly.
Thanks again,
Bryce
@Bryce, the generator script is just a ruby class, so I'm sure there's some way to call it dynamically from other code, but I don't know how exactly.
However, I doubt it is the best solution to your problem. Very rarely should you need to generate tables and rhtml files dynamically. Instead I recommend adding another layer of abstraction, so you're adding rows to a table instead of tables to the database. You can store the contents of a template in the table row as well.
The forum would be a good place to make a thread about this so you can go into more detail on what you're trying to accomplish.
Hey Ryan. Another awesome railscast. And i concur with Bryce... Id watch every day if you made them!
Does anyone know of a way to automate a Rake to run nightly or based on some set interval? For some reason I have this nasty aversion to cron jobs and being able to automate a custom Rake would be insanely useful.
Hey Ryan great screencast.
I want to make a rake task to db:migrate both development and test databases at the same time
Just wondering if you know a way to call an exisiting rake task within a rake task and pass it a parameter?
This is what I have so far:
<pre>
namespace :db do
desc "Migrate development & test"
task :all do
Rake::Task['db:migrate'].invoke
end
end
</pre>
Also is there a way to pass variables in to a rake task and access them from the task?
eg
rake db:all VERSION=0
Cheers,
Josh
Real good screencast. I was just wondering, what theme do you use for textmate? I've only just purchased it.
Thanks
@sam
Take a look at "About Railcast" for more infos about the used tools.
Thanks for this screencast! I just subscribed and I'm loving every episode.
This will work mate
namespace :migrate do
desc "Migrates development and test databases"
task :dev do
puts "Migrating development database"
Rake::Task["db:migrate"].invoke
puts "Migrating test database"
Rake::Task["db:test:clone"].invoke
puts "Test migration complete"
end
end
You just then call it like so
rake migrate:dev
Im just starting my research on this but does anyone know of a way to change the DB configs that :environment calls? It works fine locally but when i try to run this on my stage server its trying to use root @ localhost which is is the development block of our database.yml account. I need to it to use one of the others. Ill post if I find the solution. Thanks in advance!
You'll have to specify the rails environment when you call your rake task. Like this:
rake pick:winner RAILS_ENV=production
It defaults to development.
Thanks so much! I've been looking all over for a tutorial on custom rake tasks. This was a god-send.
Very useful! I just used your tutorial to automize a huge time leech in my creation of projects. Thank you.
Is it possible to define "global" rake tasks, which are available to all projects, a la ~/.rails/generators? ~/.rails/tasks isn't searched.
@Mikael, yep! See Sake:
http://errtheblog.com/posts/60-sake-bomb
What a great screencast! Thanks for taking the time to put it together.
I have found that as of Rails 2.1, you need to require 'environment' to be able to use models in a rake task
@dudzjosh:
params passed like version=0 can be accessed using ENV e.g:
if ENV.include?('version') and ENV['version'].eql?(XXX)
Thanks for this Railscast. I am trying to parse an RSS feed to add data to a new Rails site and this has been a big help.
Thanks Ryan, writing rake tasks is so easy!!! :-)
Of all the supposedly-easy tips for Rails development, this one REALLY DID WORK as simply and easily as advertised, even on our complex database.
This has saved me hours.
How we we migrate only one migration file using rake. Meaning i have a migration file named 20100628999998_load_moduls_data.rb
It has various factories which create data. I want to run only that migration/ruby file everytime, how do it do that ?
Got it!
desc "Raise an error unless the RAILS_ENV is development"
task :development_environment_only do
raise "Hey, development only you monkey!" unless RAILS_ENV == 'development'
end
task :test_data => [:environment, :development_environment_only] do
#file = Dir["db/migrate/#{ENV["VERSION"]}_*.rb"].first
file = Dir["db/migrate/*load_test_data.rb"].first
require(file)
migration_class = file.scan(/([0-9]+)_([_a-z0-9]*).rb/)[0][1].camelize.constantize
migration_class.migrate(:down) unless ENV["DIRECTION"] == 'up'
migration_class.migrate(:up) unless ENV["DIRECTION"] == 'down'
end
References:
1. Justin French for dev env only
http://justinfrench.com/notebook/a-custom-rake-task-to-reset-and-seed-your-database
2. bmihelac Blog http://source.mihelac.org/2007/02/21/running-database-migration-individually/
Hey Guys, I'm getting the following errors in Rails 2.3.5 and gte the following error when trying to access the RAND method the way Ruan does..
undefined method `RAND'
Any ideas?
I know you posted this question 1 year ago, but it could be useful for some people.
RAND() is specific to MySQL, so if you are using PostgreSQL for instance it's random().
Hi All, I cannot get my custom /lib/tasks/test.rake :greet task to run like in the railscast. From the app's root "/var/www/id360/", when I issue "rake greet" I get:
(in /var/www/id360)
rake aborted!
Don't know how to build task 'greet'
It seems that rake is not looking in /lib/tasks/ for my "test.rake".
How can I correct this?
Thanks,
Bill
I know this question is really old, but I was having the same problem and realized that my rake file was saved with a
.rb
extension instead of.rake
. Just in case anyone else has this problem in the future, this could be something to double check.I wouldn't mind seeing a Revised Railscast on this episode, that included passing arguments to rake tasks.
+1
+1!
Thanks a lot Ryan, I was looking for a way to update some existing values in a database and finally I got the answer. Thanks a lot :)
Keep up the good work
I'm fairly new to rails and everytime I google to get some info, railscasts keeps popping op. So far I've been really happy I've subscribed :)
Just an fyi, for ruby 2.0 the syntax for the pick_winner task is User.order('random()').first (vs. User.find(:first, :order => 'random()')