How to detect Rails environment inside whenever
Asked Answered
C

5

20

This question will probably only make sense if you know about the whenever gem for creating cron jobs.

For my app, I want to use whenever in all the environments, including testing and development.
My schedule.rb looks like this:

set :output, {
    :error    => "#{path}/log/error.log",
    :standard => "#{path}/log/cron.log"
}

set :environment, Rails.env.to_sym
every 5.minutes do
  rake 'db:activity:synchronize'
end

but it fails on Rails.env.to_sym (and the same stands for RAILS_ENV):

/home/marius/.rvm/gems/ruby-1.9.2-p290@uxolo/gems/whenever-0.6.8/lib/whenever/job_list.rb:21:in `eval': uninitialized constant Whenever::JobList::Rails (NameError)
    from /home/marius/.rvm/gems/ruby-1.9.2-p290@uxolo/gems/whenever-0.6.8/lib/whenever/job_list.rb:21:in `eval'
    from /home/marius/.rvm/gems/ruby-1.9.2-p290@uxolo/gems/whenever-0.6.8/lib/whenever/job_list.rb:21:in `initialize'
    from /home/marius/.rvm/gems/ruby-1.9.2-p290@uxolo/gems/whenever-0.6.8/lib/whenever.rb:15:in `new'
    from /home/marius/.rvm/gems/ruby-1.9.2-p290@uxolo/gems/whenever-0.6.8/lib/whenever.rb:15:in `cron'
    from /home/marius/.rvm/gems/ruby-1.9.2-p290@uxolo/gems/whenever-0.6.8/lib/whenever/command_line.rb:41:in `run'
    from /home/marius/.rvm/gems/ruby-1.9.2-p290@uxolo/gems/whenever-0.6.8/lib/whenever/command_line.rb:8:in `execute'
    from /home/marius/.rvm/gems/ruby-1.9.2-p290@uxolo/gems/whenever-0.6.8/bin/whenever:38:in `<top (required)>'
    from /home/marius/.rvm/gems/ruby-1.9.2-p290@uxolo/bin/whenever:19:in `load'
    from /home/marius/.rvm/gems/ruby-1.9.2-p290@uxolo/bin/whenever:19:in `<main>'

So, my question basically boils down to:

  1. How do I access the current environment, or
  2. What should I do to use whenever in all the environments?
Commemorative answered 16/8, 2011 at 20:23 Comment(0)
S
9

The error message suggests that Rails isn't defined. i.e the framework isn't loaded when you're asking the question what environment is rails running with.

In fact from looking at the code for Whenever it looks like rails isn't a requirement for it (i.e. You can install and run Whenever without rails even being installed on your system). Hence there's no way for Whenever to look at your rails environment (as far as i can tell)

Sodomite answered 16/8, 2011 at 20:37 Comment(0)
R
29

At least in newer version of whenever it is possible to access the environment with @environment. For example if you want whenever to only generate cron entries for some jobs in production:

case @environment
when 'production'
  every 1.day, :at => '0:00 am' do
    rake "some:task"
  end 
end
Rainbow answered 8/1, 2012 at 17:2 Comment(3)
In my case, this told me production instead of development, whereas the solutions of @JCoster22 worked fine (development while in development, and production on production)Moffit
Hmm the @environment variable is "production" even in development env? sounds badRainbow
@MattiasWadman: yes, the environment is production by default. I use bundle exec whenever --set "environment=development" to override this.Hollands
S
9

The error message suggests that Rails isn't defined. i.e the framework isn't loaded when you're asking the question what environment is rails running with.

In fact from looking at the code for Whenever it looks like rails isn't a requirement for it (i.e. You can install and run Whenever without rails even being installed on your system). Hence there's no way for Whenever to look at your rails environment (as far as i can tell)

Sodomite answered 16/8, 2011 at 20:37 Comment(0)
C
9

As recommended by the gem author, the solution is to pass in the current environment as a variable:

$ whenever --set environment=test
0,5,10,15,20,25,30,35,40,45,50,55 * * * * /bin/bash -l -c 'cd /home/marius/uxolo && RAILS_ENV=test rake db:activity:synchronize --silent >> /home/marius/uxolo/log/cron.log 2>> /home/marius/uxolo/log/error.log'

$ whenever --set environment=development
0,5,10,15,20,25,30,35,40,45,50,55 * * * * /bin/bash -l -c 'cd /home/marius/uxolo && RAILS_ENV=development rake db:activity:synchronize --silent >> /home/marius/uxolo/log/cron.log 2>> /home/marius/uxolo/log/error.log'

And Chris Bailey is right: Whenever itself doesn't load the Rails environment.

Commemorative answered 18/8, 2011 at 14:33 Comment(0)
O
8

A variation of the first answer to a similar question worked for me. Add

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

to the top of schedule.rb and you'll be able to call Rails.env to access the current Rails environment.

Note: the above path would be different if your environment.rb file isn't in /app/config

Oswald answered 1/10, 2012 at 13:51 Comment(0)
B
1

I took the implementation of Rails.env I found here (by clicking on "source"), and used it to initialize the ::Rails module at the beginning of the config/schedule.rb

eval %Q(module ::Rails
  def self.env
    '#{@environment}' || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
  end
end
)

This creates the Rails module, and makes its environment return what you supplied as --set environment=... in the whenever command line, as the script author suggests.

However, whenever sets the @environment to production by default, so this large "or" may be not quite useful.

Now the Rails.env call in the Whenever script would work. What was more important in my case, it also worked in other scripts I included into schedule.rb, such as the one that loaded application.yml.

P.S. The eval call is used to access @environment available in the scope of the schedule.rb script from inside the definition of a module.

Bogart answered 8/4, 2012 at 19:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.