Skip to content
This repository

NoMethodError with delayed_job #323

Closed
tshr opened this Issue December 22, 2011 · 28 comments
Toshiro Ken Sugihara

I am trying to implement delayed_job for a mailer on a rails 3.1.0 app locally with ruby 1.8.7 .

Following the documentation I am making the delay call from my controller as follows:

EventMailer.delay.event_message_email(current_user, @event_message)

This causes the task to be added to the job table but when I run rake jobs:work it logs the following error:

Class#event_message_email failed with NoMethodError: undefined method `event_message_email' for Class:Class - 6 failed attempts

Calling the mailer method without delay works fine, and I am running it on the default rails server so its not the issue with Thin mentioned in the FAQ. Any idea whats wrong? Thanks.

Daniel Morrison
Toshiro Ken Sugihara

Thanks for replying. Assuming you mean exiting and then rerunning the task rake jobs:work then, yes. Also I did check the jobs table and the jobs are being saved there, and the tasks are retried regularly as expected but just always fail.

Brian Ryckbost
Owner

Which version of delayed_job is this? 2.X or one of the prerelease 3.0s?

Toshiro Ken Sugihara

Ah its one of the preleases: 3.0.0.pre4, is there a better one to use?

Clay H

I'm having this same issue running on heroku cedar stack with delayed_job (3.0.0.pre4). I run the same version in my dev environment, however, and it works without a problem.

More info:

I'm calling this in my User model:

def mail_confirmation
  UserMailer.registration_confirmation(self).deliver
end

UserMailer looks like this:

class UserMailer < ActionMailer::Base
  default from: "admin@mysite.com"

  def registration_confirmation(user)
    @user = user
    mail(
          :to => "#{user.full_name} <#{user.email}>", 
          :subject => "Registered at My Site"
        )
  end

end

I get this error on heroku:

Class#registration_confirmation failed with NoMethodError: undefined method `registration_confirmation' for Class:Class - 2 failed attempts
Clay H

Looks like the same as issue 306

Toshiro Ken Sugihara

Hi, I asked this question on stackoverflow and there was a useful reply:

http://stackoverflow.com/questions/8602203/nomethoderror-with-delayed-job-collectiveidea-gem

He said that the !ruby/object:Delayed::PerformableMailer in the handler field should be recorded as !ruby/struct:Delayed::PerformableMailer. I tried changing this directly in my dev database for a queued job and when I ran rake jobs:work it did remove it from the table (it did not say the task was executed in the shell, but perhaps that i as expected). The responder recommends downgrading to 2.1.2, but I am concerned this will not work with Rails 3 mailers. Can you suggest any other solution?

Toshiro Ken Sugihara

I went ahead and switched to using 2.1.2 and this resolved the issue both on dev and production

lstone

I also have the exact same issue.

Aditya Sanghi

same issue. Using Rails 3.0.10 with ruby1.8.7

Aditya Sanghi

On the console

YAML.load MyActiveRecordModel.to_yaml
=> Class
YAML.parser.class.name
=> "YAML::Syck::Parser"

I'm running on ruby1.8.7, Rails 3.0.10, gem 1.8.11, bundler version 1.0.21
Tried with same result on Ubuntu/OSX
Tried with development mode and production mode with similar results

MyActiveRecordModel.to_yaml
=> "--- !ruby/class MyActiveRecordModel\n"

Peter Lubell-Doughtie
pld commented January 08, 2012

Same issue using Rails 3.1.0, Ruby 1.8.7, gem 1.8.15, bundler 1.0.21.

The database shows the wrong class:


When called on the ```submit``` method, this fails with the error
```Class#submit failed with NoMethodError: undefined method `submit' for Class:Class```

I can also confirm that downgrading to 2.1.2 resolves the issue.  With the database entry now correct:
```!ruby/struct:Delayed::PerformableMailer```
Mark Harper

Same issue using rails 3.1.0, ruby-1.9.2, gem "delayed_job_active_record" (delayed_job 3.0).

Downgraded to 2.1.4 resolved the issue.

Please Note: 2.1.2 and 2.1.3 have issues when I've run them using ruby-1.9.2 as follows:

delayed_job-2.1.3/lib/delayed/yaml_ext.rb:30:in remove_method: method to_yaml not defined in Class (NameError)

benhoskings@c3a28f9#diff-0

Brian Ryckbost
Owner

With the latest comments, it seems serialization is the issue and the overrides aren't catching the performable mailers.

Aditya Sanghi

@bryckbost yes the problem is with serialization but it's not limited to performable mailers. I'm seeing the problem when using delay as a class method on any class.

Brian Ryckbost
Owner

There's a fix in 0234444. If possible, can I get some verification this fixes the issue?

Turadg Aleahmad

@bryckbost yes, it's fixed. I had the same problem (Ruby 1.9.3, Rails 3.2rc2, Heroku Cedar) and after switching from the released gem to the current git master, it went went away.

Note to others, the handler inserted is still --- !ruby/object:Delayed::PerformableMailer.

Brian Ryckbost bryckbost closed this January 18, 2012
HagerAli

I have faced same problem I was

ruby 1.9.2-p290 , rails 3.0.3 , and delayed_job 2.1.2 , daemons 1.1.5

downgrading ruby version to 1.9.2-p0 solved the problem.

Kyle J. Ginavan

I' have this the following:

rbenv local 1.9.2-p290
gem "rails", "3.2.1"
gem "daemons", "1.1.8"
TRIED BOTH
gem "delayed_job", :git => "https://github.com/collectiveidea/delayed_job.git", :ref => "cd89cbb55886af597028e2618f16131200aad4b9"
AND
gem "delayed_job", "3.0.1"
gem "delayed_job_active_record", "0.3.2"

However, I still receive Delayed::PerformableMailer... error described here.

Matt Gauger

This is still an issue with the released version as well as Github master HEAD revision.

Please reopen.

Brian Ryckbost
Owner

@mathias Shoot, sorry to hear it's still an issue for you. Can you let me know which version of Ruby you're on, the backend you're using and if Rails, which version?

Thanks.

Kyle J. Ginavan

@bryckbost I have that info in my comment. PSQL is my backend.

Matt Gauger

Pulling versions out of the .rvmrc and Gemfile here:

ruby-1.9.3-p125,

delayed_job_active_record (0.3.2)
activerecord (> 2.1.0)
delayed_job (3.0.1)

rails (3.2.1)
actionmailer (= 3.2.1)

Server environment is Heroku Cedar with PostgreSQL, but we weren't getting Mailers to send mail locally in our tests, so we haven't been able to get this out to the server yet.

Brian Ryckbost
Owner

@mathias And you're experiencing NoMethodErrors with your mailers in your tests?

Olivier El Mekki

Hello,

I had the same issue locally, using :

gem 'delayed_job', '3.0.1'
gem 'delayed_job_mongoid', '1.0.8'

The problem was that we use syck as yaml engine (and we can't change for psych). In Delayed::Job::Base#payload_object, when the instance is deserialized, syck will create a Class instance in @object instead of the original class (which was an UserMailer, in our case).

Since This method is only called in a worker, when handling jobs, I monkey patched it to change yaml engine on the fly. I also had to patch PerformableMailer#perform, because it was sending "String 'UserMailer' has no method <our mailer method>" errors.

Here is my patch.

It works well locally and fix the errors.

But sending mails on heroku (on cedar stack) will simply fail without any error. Delayed job logs show the job has been processed, with "0 fail", but don't show the "sending mail to" log line as expected, and doesn't send mail. I suspect it has something to do with exceptional rescuing the exception or something.

At this point, I can't affirm the heroku app problem is a delayed_job one. I'll keep you posted, my next move will be to downgrade delayed_job and delayed_job_mongoid and see if it helps.

Olivier El Mekki

Ok, downgrading didn't help, same issue occured.

I tried that, in a heroku rails console :

irb(main):001:0> class Foo; def self.bar; throw Exception.new('hello'); end; end
=> nil

irb(main):002:0> Foo.delay.bar
=> #<Delayed::Backend::Mongoid::Job _id: 4f6dd37ad8cbd00004000004, _type: nil, created_at: 2012-03-24 14:00:26 UTC, updated_at: 2012-03-24 14:00:26 UTC, priority: 0, attempts: 0, handler: "--- !ruby/object:Delayed::PerformableMethod \nargs: []\n\nmethod_name: :bar\nobject: !ruby/class Foo\n", run_at: 2012-03-24 14:00:26 UTC, locked_at: nil, locked_by: nil, failed_at: nil, last_error: nil, queue: nil>

and got, in rake jobs:work output :

[Worker(host:<host> pid:4)] 1 jobs processed at 15.0934 j/s, 0 failed ...

It should have failed on object deserialization anyway, since Foo doesn't exist in the memory context the worker is launched in, but, heh, I would have loved to have any error.

It's worth mentionning that we were previously on a bamboo stack, with the same code and delayed_job gems versions, and everything ran just fine.

I've requested an exceptional's interface access to my CTO. More on this later.

Jason Kroll

@oelmekki thank you for your solution, it fixed the Delayed Job NoMethodError problem for me!

I then had to require some models which were present when I ran payload_object.perform locally or from Heroku console but were missing when my Heroku worker called jobs:work on its own, producing this error:

"Delayed::DeserializationError: Job failed to load: undefined class/module ModelMyMailerNeeded"

Just mentioning this in case anyone else has this problem and downgrading does not work. Just remember to load whatever models and libs your mailers need.

Pavel Tsiukhtsiayeu

Had the same YAML serialization problem on Heroku Cedar stack, Ruby 1.9.2, Rails 3.1.12, DJAR 4.0.0. It seems like web server was using different serializer than DJ. Changing Procfile helped to solve the problem: web: bundle exec thin start -R config.ru -e $RACK_ENV -p $PORT to web: bundle exec rails server thin -p $PORT -e $RACK_ENV

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.