Thu, 18 Jan 2007

Using ActiveRecord outside Rails Part II

Posted by Ben Thu, 18 Jan 2007 15:26:00 GMT

I previously posted about using ActiveRecord outside Rails last week. Since the post I’ve discovered a problem with the method when I rolled it out to my server (using the production environment) and read an excellent blog post on why that particular method is just plain WRONG!

I must admit the previous method did feel like it was a hack, and one of DHH’s goals with Rails is to encourage developers to do the right thing. Consequently, if you end up doing something that feels wrong because it is hard and/or ugly you should stop as there is probably an easier, Rails-esque way.

Rake

Rake, in the context of your Rails app, has everything you need to write a quick and DRY process that accepts arguments and can run all of your lovely tasks whenever you like.

By using rake we get access to all of the Rails application for free. So instead of loading Rails manually, a simple rake task can run any Ruby code in the application’s context.

HOWTO

Create a new file in lib/tasks with the extension .rake with your required task:

desc 'example of a rake task'
task :my_task => :environment do
  # Your code goes here
end

To invoke it simply cd to your rails directory and run rake with your task name (optionally specify the Rails environment). The code inside the task will have full access to your Rails environment including models.

cd /path/to/rails/application
rake <task_name> RAILS_ENV=production 

You can check that the task is available by looking at the output of rake --tasks. (Any .rake files in the lib/tasks directory should be automatically included).

As a final note you could use this for scheduled tasks by running the above code via UNIX cron or a Windows scheduled task. I’ve updated my script from the previos method as a Rake task and it now works perfectly in production mode.

References

Script vs Rake…

Comments

Leave a response

  1. http://www.soledadpenades.com/ about 1 month later:

    Good one! I was trying to do something like you do (parsing feeds in a cron manner) and found your page. The second part is even better, hadn’t thought of using rake for this. Great great great.

    I should tag you as lifesaver in del.icio.us :-)

  2. Andy Greenberg 3 months later:

    Doh!!! This is so right, compared to the monstrosity I was building. While Rails still doesn’t have an elegant and uniformly useful mechanism for background periodic tasks (dbBackground, while promising, still doesn’t appear to work properly in my configuration), this is a workable solution for the time being.

  3. mla 5 months later:

    Don’t you think there should be a simple way to use a model outside of Rails? Both of these solutions are very tightly coupled to the Rails framework. Having to use rake to run what should be a stand-along script seems very ugly.

  4. raovijay@gmail.com 10 months later:

    I have a task that parses some files and populates data in the database. I did as you described but how do I run it?

    I mean I went into the tasks folder inside lib and then typed ‘rake taskname’ However I got the following error

    rake aborted! Don’t know how to build task ‘load_vta_data.rake’ C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/rake-0.7.2/lib/rake.rb:1473:in `[]’ C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/rake-0.7.2/lib/rake.rb:1935:in `run’ C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/rake-0.7.2/lib/rake.rb:1935:in `each’ C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/rake-0.7.2/lib/rake.rb:1935:in `run’ C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/rake-0.7.2/bin/rake:7 C:/InstantRails/ruby/bin/rake.bat:20:in `load’ C:/InstantRails/ruby/bin/rake.bat:20

    Please help.

  5. Ben 10 months later:

    Raovijay, you can view a list of all available rake tasks via rake -T (do this from the Rails application’s root folder – any .rake files in the lib directory are automatically included).

    Ensure your new task is shown and then simply run it via rake taskname (don’t include the .rake extension).

  6. makuchaku about 1 year later:

    This is a lifesaver indeed!

    :) Maku

Comments