Intro to Rake
- Introduce Rake and Rake tasks.
- Understand what Rake is used for in our Ruby programs.
- Learn how to build a basic Rake task.
What is Rake?
Rake is a tool that is available to us in Ruby that allows us to automate
certain jobs––anything from execute SQL to
puts-ing out a friendly message to
Rake allows us to define something called "Rake tasks" that execute these jobs. Once we define a task, that task can be executed from the command line.
Every program has some jobs that must be executed now and then. For example, the task of creating a database table, the task of making or maintaining certain files. Before Rake was invented, we would have to write scripts that accomplish these tasks in BASH, or we would have to make potentially confusing and arbitrary decisions about what segment of our Ruby program would be responsible for executing these tasks.
Writing scripts in BASH is tough, and BASH just isn't as powerful as Ruby. On the other hand, for each developer to make his or her own decisions about where to define and execute certain common tasks related to databases or file maintenance is confusing.
Rake provides us a standard, conventional way to define and execute such tasks using Ruby.
Where did Rake Come From?
In fact, the C community was the first to implement the pattern of writing all their recurring system maintenance tasks in a separate file. They called this file the MakeFile because it was generally used to gather all of the source files and make it into one compiled executable file.
Rake was later developed by Jim Weirich as the task management tool for Ruby.
How to Define and Use Rake Tasks
Building a Rake task is easy, since Rake is already available to us as a part of
Ruby. All we need to do is create a file in the top level of our directory
Rakefile. Here we define our task:
task :hello do # the code we want to be executed by this task end
We define tasks with
name of task as a symbol + a block that contains
the code we want to execute.
If you open up the
Rakefile in this directory, you'll see our
task :hello do puts "hello from Rake!" end
Now, in your terminal in the directory of this project, type:
You should see the following outputted to your terminal:
hello from Rake!
Describing our Tasks for
Rake comes with a handy command,
rake -T, that we can run in the terminal to
view a list of available Rake tasks and their descriptions. In order for
rake -T to work though, we need to give our Rake tasks descriptions. Let's give our
hello task a description now:
desc 'outputs hello to the terminal' task :hello do puts "hello from Rake!" end
Now, if we run
rake -T in the terminal, we should see the following:
rake hello # outputs hello to the terminal
Namespacing Rake Tasks
It is possible to namespace your Rake tasks. What does "namespace" mean? A
namespace is really just a way to group or contain something, in this case our
Rake tasks. So, we might namespace a series of greeting Rake tasks, like
hello, above, under the
Let's take a look at namespacing now. Let's say we create another greeting-type
desc 'outputs hola to the terminal' task :hola do puts "hola de Rake!" end
Now, let's namespace both
hola under the
namespace :greeting do desc 'outputs hello to the terminal' task :hello do puts "hello from Rake!" end desc 'outputs hola to the terminal' task :hola do puts "hola de Rake!" end end
Now, to use either of our Rake tasks, we use the following syntax:
rake greeting:hello hello from Rake! rake greeting:hola hola de Rake!
Common Rake Tasks
As we move towards developing Sinatra and Rails web applications, you'll begin to use some common Rake tasks that handle the certain database-related jobs.
One common pattern you'll soon become familiar with is the pattern of writing code that creates database tables and then "migrating" that code using a rake task.
Student class currently has a
#create_table method, so let's use that
method to build out our own
migrate Rake task.
We'll namespace this task under the
db heading. This namespace will contain a
few common database-related tasks.
We'll call this task
migrate, because it is a convention to say we are
"migrating" our database by applying SQL statements that alter that database.
namespace :db do desc 'migrate changes to your database' task :migrate => :environment do Student.create_table end end
But, if we run
rake db:migrate now, we're going to hit an error.
You might be wondering what is happening with this snippet:
task :migrate => :environment do ...
This creates a task dependency. Since our
Student.create_table code would
require access to the
config/environment.rb file (which is where the student
class and database are loaded), we need to give our task access to this file. In
order to do that, we need to define yet another Rake task that we can tell to
run before the
migrate task is run.
Let's check out that
# in Rakefile task :environment do require_relative './config/environment' end
After adding our environment task, running
rake db:migrate should create our
Another task you will become familiar with is the
seed task. This task is
responsible for "seeding" our database with some dummy data.
The conventional way to seed your database is to have a file in the
db/seeds.rb, that contains some code to create instances of your
If you open up
db/seeds.rb you'll see the following code to create a few
require_relative "../lib/student.rb" Student.create(name: "Melissa", grade: "10th") Student.create(name: "April", grade: "10th") Student.create(name: "Luke", grade: "9th") Student.create(name: "Devon", grade: "11th") Student.create(name: "Sarah", grade: "10th")
Then, we define a rake task that executes the code in this file. This task will
also be namespaced under
namespace :db do ... desc 'seed the database with some dummy data' task :seed do require_relative './db/seeds.rb' end end
Now, if we run
rake db:seed in our terminal (provided we have already run
rake db:migrate to create the database table), we will insert five records
into the database.
If only there was some way to interact with our class and database without having to run our entire program...
Well, we can build a Rake task that will load up a Pry console for us.
We'll define a task that starts up the Pry console. We'll make this task
dependent on our
environment task so that the
Student class and the database
connection load first.
desc 'drop into the Pry console' task :console => :environment do Pry.start end
Now, provided we ran
rake db:migrate and
rake db:seed, we can drop into our
console with the following:
This should bring up the following in your terminal:
Let's check to see that we did in fact successfully migrate and seed our database:
 pry(main)> Student.all => [[1, "Melissa", "10th"], [2, "April", "10th"], [3, "Luke", "9th"], [4, "Devon", "11th"], [5, "Sarah", "10th"]]
We did it!
View Intro to Rake on Learn.co and start learning to code for free.