2

I am using whenever gem to create a cron job. This cron job needs to run a helper method on my rails app at a regular interval. This helper method checks every instance of my model and decides to update it or not.

/app/helpers/auctions_helper.rb:

module AuctionsHelper

  def self.checkForExpiredAuction
    # method to update each auction that has expired
    puts "There are currently #{Auction.count} auctions."

    @auctions = Auction.all
    @auctions.each do |auction|
      if auction.end_time > Time.now.utc
        auction.price = 1000000
        auction.save
        puts "just updated #{auction.product} auction"
      end
    end
    puts "just updated any auctions that had expired"
  end
end

schedule.rb:

set :output, "log/cron_log.log"
every 1.minute do
  runner "AuctionsHelper.checkForExpiredAuction"
end

which creates the following cronjob:

# Begin Whenever generated tasks for: bestBay
            * * * * * /bin/bash -l -c 'cd /home/bestbay && script/rails runner -e production '\''AuctionsHelper.checkForExpiredAuction'\'' >> log/cron_log.log 2>&1'
#    End Whenever generated tasks for: bestBay

The problem I'm having is that the helper method can't access the table 'auctions'. From my cron_log.log:

Could not find table 'auctions' (ActiveRecord::StatementInvalid)

This doesn't seem to be a problem with the helper method itself. If I run from terminal:

rails runner AuctionsHelper.checkForExpiredAuction

I get a nice set of outputs from my puts messages. So why can't my cronjob access my model/table?

tir38
  • 9,810
  • 10
  • 64
  • 107
  • Which version of Rails are you using? If you're on 3.x then you should use the `task` option instead of `runnner`, which should result in a command wrapped in `bundle exec ` -- bundler ensures that your full and normal rails environment (and gems, etc.) are loaded. – Tom Harrison Nov 16 '12 at 21:43
  • from DOCS: doesn't runner already do this: "The default job types that ship with Whenever are defined like so: ... job_type :runner, "cd :path && script/rails runner -e :environment ':task' :output" ...." – tir38 Nov 18 '12 at 20:42

3 Answers3

3

The basic problem was that cron wasn't spooling up the same environment variables as when I just opened a shell prompt. I also had a .rvm file that was loading my ruby environment and getset every time I cd'd into the main application directory. I finally had to do this:

# set the cron log location
set :output, {:error => '/home/jason/bestbay/log/cron_error.log', :standard => '/home/jason/bestbay/log/cron_status.log'}
set :job_template, "bash -i -c ':job'"
env :PATH, ENV['PATH']

every 1.minute do
  #command "echo $PATH"                             # confirm shell variable PATH was loaded
  #command "cd #{path}"                             # this is not needed
  #command "pwd"                                    # visualize current directory
  #command "rvm current"                            # visualized default ruby version and gemset
  command "rvm use ruby-1.9.3-p194@cmucourse"       # set desired gemest
  #command "rvm current"                            # visualize proper gemset load

  runner "AuctionsHelper.checkForExpiredAuction", :environment => 'development' # run method
end

I'm including the commented out commands because they really helped me visualize what was happening when cron ran.

tir38
  • 9,810
  • 10
  • 64
  • 107
0

I think by default the runner will run in RAILS_ENV=development while the cron line is wired to run on "production" environment.

Try this:

RAILS_ENV=production rails runner AuctionsHelper.checkForExpiredAuction

If you get the same error, then that is the problem

For testing, point your production environment to your development, in database.yml

production:
  development
Samer Buna
  • 8,821
  • 9
  • 38
  • 55
0

whatever defaults to production and will by default look for a production database. To change this behaviour you can update the crontab and set it to development as such:

whenever --update-crontab --set environment='development'

Hope this saves someone a bit of time as it had me for a while.

Gino
  • 1,043
  • 16
  • 27