Search code examples
ruby-on-railsrubyherokurakewhenever

NoMethodError: undefined method ' ' for main:Object - whenever scheduler


I can't get reminder.rake to work in production. I get an error.

namespace :challenges do
  desc 'Send email to users with challenges who want reminder'
  task challenge_reminder: :environment do
    self.all.each do |challenge|
      UserMailer.challenge_reminder(self).deliver_now # Tried (challenge) instead of (self), same error too
    end 
  end
end

heroku scheduler

enter image description here

trace error

Anthony-Gallis-MacBook-Pro:livetochallenge galli01anthony$ heroku run rake challenges:challenge_reminder --trace
Running rake challenges:challenge_reminder --trace on livetochallenge... up, run.7666
rake aborted!
NoMethodError: undefined method `all' for main:Object
/app/lib/tasks/reminder.rake:4:in `block (2 levels) in <top (required)>'
Tasks: TOP => challenges:challenge_reminder
(See full trace by running task with --trace)
Anthony-Gallis-MacBook-Pro:livetochallenge galli01anthony$

As an example I have below working so I know it isn't a problem with setting up the whenever gem or heroku scheduler:

namespace :challenges do
  desc 'Clean the challenge freebies and freebie_dates'
  task clean: :environment do
    Challenge.update_all(freebie: 0, freebie_date: nil)
  end
end

Solution

  • There's a problem here with your Rake task:

    task challenge_reminder: :environment do
      self.all.each do |challenge|
        UserMailer.challenge_reminder(self).deliver_now
      end 
    end
    

    Here self refers to the Rake task context, not the model where this code originated. You'll also need to do something with challenge or there's no point in retrieving it.

    Suggested fix:

    task challenge_reminder: :environment do
      Challenge.all.each do |challenge|
        UserMailer.challenge_reminder(challenge).deliver_now
      end
    end
    

    Remember that calling .all on a model with a lot of records may use enormous amounts of memory and could crash your server if it gets too huge because Rails will load every single record into memory. If you have millions of those, you're probably toast.

    When trying to trace back to problems, look at the line referenced in the error first and work back from there. Ruby's stack trace is usually specific enough to get to the root of the problem.