Take the 2-minute tour ×

I have a background process that modifies records in a database. The models connect to the database using something like this:

dbconfig = YAML::load(File.open('database.yml'))
class Clcar < ActiveRecord::Base

All model classes have those lines at the top.

I agree that's a bad way of doing it.

  1. Is there a better way to get a connection to a model class? How do I pass the connection to the model?
  2. I want to be able to run my background process with a different environment, say "production".

How do I achieve that?

share|improve this question
Use YAML.load_file instead of load and File.open. –  Ryan Bigg May 5 '11 at 3:10
add comment

2 Answers

up vote 11 down vote accepted

I would set up the connection once at the start of your background process. Once you've established the connection once, all of the models will work correctly anyway.

Your connection establishment code would look something like this:

@environment = ENV['RACK_ENV'] || 'development'
@dbconfig = YAML.load(File.read('config/database.yml'))
ActiveRecord::Base.establish_connection @dbconfig[@environment]
share|improve this answer
Definitely solves one problem. But how would you run different environments eg: production, development with it? Thanks –  truthSeekr May 5 '11 at 2:46
I set the same environment variables in my background scripts as my main environment. So I run my background command with RACK_ENV=production ruby run_stats_updater.rb, and inside my code I use @environment = ENV['RACK_ENV'] || 'development' to determine which environment to use. –  Jamie Penney May 5 '11 at 3:03
That's very helpful. Thank you. –  truthSeekr May 5 '11 at 5:09
add comment

I'd recommend looking into using rails runner.

Runner scripts have access to everything, including the database, but without all the view stuff from the MVC model. They are great for back-end tasks or jobs that work on the database but don't have any interface.

You can also use rails rake instead, but I feel rake tasks are targeted at maintenance of the files and directories and for building structure, and runner scripts better for regular tasks, such as something you'd run from cron periodically.

I have one I use for retrieving logs from a site, parsing them, then injecting them into one of my databases. There's no reason to run the job as part of the Rails app because there was no need for an interface. Running as a runner script fit nicely.

The built-in help says:

Usage: runner [options] ('Some.ruby(code)' or a filename)

    -e, --environment=name           Specifies the environment for the runner to operate under (test/development/production).
                                     Default: development

    -h, --help                       Show this help message.

You can also use runner as a shebang line for your scripts like this:
#!/path/to/your/rails/app/script/rails runner

Product.find(:all).each { |p| p.price *= 2 ; p.save! }

That last line:


shows how easy it is.

share|improve this answer
Thank you. Looks like something I could use. Will definitely look into it. –  truthSeekr May 5 '11 at 2:42
This looks handy, but it would pull in the entire rails stack which would bloat the process running it. I might look at using it for some of my infrequently run scripts though, thanks. –  Jamie Penney May 5 '11 at 23:40
If all that is needed is ActiveRecord and maybe Active_Support, it's real easy to load them in directly without the rest of the Rails stack. I've done that too. ActiveRecord checking the database structure and building the models is probably the slowest part of using a runner script though, so it's hard to avoid the initial pause. –  the Tin Man May 6 '11 at 0:00
add comment

Your Answer


