What Exactly Is Rake

What exactly is Rake?

Try Martin Fowler's article on Rake for more information:

http://martinfowler.com/articles/rake.html

His pre-amble is:

Rake is a build language, similar in
purpose to make and ant. Like make and
ant it's a Domain Specific Language,
unlike those two it's an internal DSL
programmed in the Ruby language. In
this article I introduce rake and
describe some interesting things that
came out of my use of rake to build
this web site: dependency models,
synthesized tasks, custom build
routines and debugging the build
script.

There is more information available on or linked from the project's home page as well:

http://rake.rubyforge.org/

What is the purpose of Rake?

Rake lets you script certain tasks on a per-project basis, much as a Makefile allows a Unix developer to script their compile and build process. The defined tasks you've used Rake with so far were included with the packages they came with (e.g. rake db:migrate comes with Rails, or at least with ActiveRecord) and automate certain tasks related to those packages (e.g. installing required gems for a Rails project).

If your project has certain tasks which are performed repeatedly, you can write a rake task to run those tasks which gets included in the SCM tree for the project and runs in the context of that project; in Rails they're in lib/tasks. You could write a Rake task to purge stale session records from your database, for example, and then set up a cron job to run it.

exactly what does rake db:migrate do?

Everytime you create a migration using scripts (like script/generate model ...) a new migration is added to the correct directory ready to be synched with the real database.

Actually rake db:migrate just checks which missing migrations still need to be applied to the database without caring about the previouse ones.

Of course if you modify the database using other ways is common to obtain out-of-synch things because as you said you can find yourself applying a migration to something that is changed underneath.

Difference between rake and bin/rake

  • rake and bin/rake

Rake is a program that you installed on your computer. To use it in your terminal, you use rake do:something. Using directly rake means that a shortcut has been created, an alias saying "when I type rake I want to use the program located in [...]".

The bin/rake style is not using the alias created but the path of the program. Usually the programs' executor (not the program's content, just the launcher) are located in the folder /bin/. To determine the full path of a specific program, use which:

[yoshiji:~] $ which rake
/home/yoshiji/.rvm/gems/ruby-1.9.3-head@yourproject/bin/rake
[yoshiji:~] $ which ls
/bin/ls
  • RAILS_ENV=production rake do:something

This RAILS_ENV part is here to specify an environment Rails should load when running the rake command. By default the environment is development.


To summarize:

  • rake assets:precompile : Use the alias/shortcut rake
  • /bin/rake assets:precompile : Use the full path to the rake program
  • RAILS_ENV=production rake assets:precompile : Specify Rails to load the production environment when executing the rake task assets:precompile

How does rake db::migrate actually work

Note: This is true so far as Rails 2.x. It may not hold true for rails 3, as I haven't spent as much time with Rails 3 as I would have liked.

Rails creates a special hidden table named schema_migrations. This table has a single column named version. And there is a row in this column for every migration you have. The value being the timestamp that matches the migrations filename timestamp.

When you migrate, it looks through all your migrations in chronological order (also happens to be alphabetical order due to the timstamp based naming convention). For every migration it looks for a matching row in the schema_migrations table. If it fails to find one, then it runs that migration, and adds the timestamp the table. If it does find one, it assumes it already ran and simply skips it.

The result is that 2 developers can both commit migrations in any order, and it's fine. This is because Rails knows exactly what migrations have been run and which haven't, regardless of when your database first saw them.

So to do something yourself like this, you simply need a way to permanently store this state about which steps been taken and which have not.

what does rake db:schema:cache:dump exactly do? is it safe to be ran in production?

After logging my DB and running the command, it turns out it just runs

show full fields table_name

against all the tables in the schema.

Is there a 'Rake-like' design pattern?

If what you're talking about is the actual dependency management, I wouldn't call it a design pattern.

Read about how to do a topological sort of a directed acyclic graph, dependency management boils down to that.

I think it's highly possible that such a library exists.

Edit

I just found this library, it might prove useful. Actually it's a fairly large library, but it contains a class that does (or claims it can do) the topological sorting.

I should add that I'm pretty sure there isn't a design pattern that deals with this. Figuring out in which order a given sequence of interdependent tasks should be completed is just a graph theory problem. The wikipedia articles I linked contain pretty much everything you need to know.

Shouldn't that class work, I figure it wouldn't be difficult to implement it from scratch, or by translating from another language (Python for instance: I seem to recall that Twisted provides you with such a capability).

Even more edit

I don't think implementing dependency management in your app would be just another case of wheel reinvention. If you need it, code it. That is, unless you can find a generic, working library with a compatible license that suits your need. In that case, by all means use it. It really is that simple.

What steps are followed after you say rake install?

a rake file is a collection of tasks, when you call rake with an argument (in this case install) that's the task that get's executed. (It's similar to ant if you come from Java)

So, no, rake does not execute the whole rakefile when you call "rake + task" but only the task chosen. Note that tasks can have dependencies (eg the "test" task may depend on other previous tasks, like creating some folders and stuff for the tests to run).

Lastly, the rake user guide as pointed by other users is useful, but I recommend a more enjoyable read here -> Ruby on Rails Rake tutorial.



Related Topics



Leave a reply



Submit