8
votes

I have a Ruby script in my Rails app that I use to load some data from Twitter.

In the future I will make it an automatic background process, but for now I run it manually like:

ruby /lib/twitter/twitterLoad.rb

In order to use the Rails model classes and such, I have the following as the top line of the script:

require "#{File.dirname(__FILE__)}/../../config/environment.rb"

By default, the development environment is used. But, I'd like to be able to choose the production environment at some point.

Update #1: The RAILS_ENV constant is getting set in the environment.rb file. So, I was able to put ENV['RAILS_ENV'] = 'production' at the very top (before the environment.rb) line and solve my problem somewhat. So, my new question is, can do pass in env vars through the command line?

7

7 Answers

24
votes

If you're going to be using the rails environment, your best bet would be to make this a rake script. To do this, put a twitter.rake file into lib/tasks and begin and end it like this:

task(:twitter_load => :environment) do
  # your code goes here
end

That way, you're doing it by "following conventions" and it doesn't have that 'orrible smell associated with it.

10
votes

I currently use the following method, and I know the environment doesn't have the rb extension, it's not needed. You can also set it before running it to overwrite the ENV["RAILS_ENV"].

#!/usr/bin/env ruby

# Set your environment here.
ENV["RAILS_ENV"] ||= "production"

require File.dirname(__FILE__) + "/../../config/environment"

puts "Rails was loaded!"

Then to change the environment, just run it with:

rb /lib/tasks/file.rb RAILS_ENV=development
5
votes

Don't forget script/runner.

Set your environment variable from the command line and

ruby script/runner your_script_here.rb
2
votes

The accepted answer to use rake is well-taken, but you may still want to manually set the environment for testing utility classes.

Here's what I use to set up the test environment for utility classes in /lib. For these I tend to use the Ruby convention of making my class file execute its tests when it gets run from the command line. This way I can do TDD outside of Rails' web-centric test harnesses, but still use the class within rake without affecting the environment that it sets.

This goes at the top:

if (__FILE__ == $0)
  ENV['RAILS_ENV'] ||= 'test'
  require File.join(File.dirname(__FILE__),'../config/environment.rb')
end

and this goes at the bottom:

if (__FILE__ == $0)
  require 'test/unit/ui/console/testrunner'
  Test::Unit::UI::Console::TestRunner.run(MyClassTest)
end
1
votes

You can also do

script/console development < path/to/your/script.rb

Admiteddly cumbersome -and will spit out lots of irb garbage after evaluating each and every line of your script- but works for quickies and you dont have to remember that damned require line.

And don't forget that maybe the most elegant way to extend your app with scripts that do useful things is writing Rake tasks!

0
votes

add the line: RAILS_ENV = '<your environment of choice>'

http://wiki.rubyonrails.org/rails/pages/Environments#script

pantulis: It's cool that that works, but for quickies I just use RAILS_ENV = '<your environment of choice>' ruby path/to/script.rb. This is how you set environment variables in the console.

0
votes
require 'bundler'
require 'bundler/setup'

ENV['RAILS_ENV'] ||= 'development'

RAILS_ROOT = Pathname.new(File.expand_path('~/path/to/root'))

puts "Loading Rails Environment from #{RAILS_ROOT}..."
require RAILS_ROOT.join('config/environment').to_s

This works but only if the Gemfile of your script contains all the dependencies of your rails app. You might be able to load one Gemfile from another, e.g just eval it, to overcome this copy/paste.