Rails: Absolutely stumped with delayed_job. Not receiving arguments anywhere

£可爱£侵袭症+ 提交于 2019-12-01 02:59:58

问题


I'm trying to send mail in a Rails 3 application using collectiveidea's delayed_job. If I try to send mail regularly (.deliver) it works fine, but as soon as I switch to delayed job, things fall to pieces.

The standard error I get in the delayed_job mysql table is:

{undefined method `name' for nil:NilClass...

where 'name' is the first argument in the mailer's view (@contact.name). This works fine if I take delayed_job out again.

If I remove all references to @contact in the view, I get

{A sender (Return-Path, Sender or From) required to send a message

In short, it doesn't seem to be understanding any arguments at all.

All relevant code below - if anyone has any suggestions for this it would be very appreciated

CONTROLLER

  def sendmail
    @contact = Contact.new(params[:contact])
    if @contact.save
      ContactMailer.delay.contact_mail(@contact)
      flash[:notice] = 'Your message has been successfully sent'
      redirect_to root_path
    else
      render :action => 'index'
    end
  end

MAILER:

class ContactMailer < ActionMailer::Base
  default :from => "my@email.address"  

  def contact_mail(contact)
    @contact = contact
    mail(:to => 'my@email.address', :subject => 'Contact Form Query', :from => 'my@email.address', :content_type => 'text/plain')
  end
  handle_asynchronously :contact_mail, :run_at => Proc.new { 2.seconds.from_now }
end

MAILER VIEW:

You have received a new query:
-----------------------------------

<%= @contact.name %>

<%= @contact.business %>

<%= @contact.phone %>

-----------------------
<%= @contact.message %>
-----------------------

INITIALIZER:

Delayed::Worker.destroy_failed_jobs = false
Delayed::Worker.max_run_time = 5.weeks

And finally, the full error message:

    {undefined method `name' for nil:NilClass

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/activesupport-3.0.0/lib/active_support/whiny_nil.rb:48:in `method_missing'

/Users/john/Websites/Rails/InDevelopment/connectted/app/views/contact_mailer/contact_mail.html.erb:4:in `_app_views_contact_mailer_contact_mail_html_erb___3386534441642202773_2166008980__4301703149293725172'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0/lib/action_view/template.rb:135:in `block in render'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/activesupport-3.0.0/lib/active_support/notifications.rb:54:in `instrument'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0/lib/action_view/template.rb:127:in `render'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0/lib/action_view/render/rendering.rb:59:in `block in _render_template'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/activesupport-3.0.0/lib/active_support/notifications.rb:52:in `block in instrument'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/activesupport-3.0.0/lib/active_support/notifications/instrumenter.rb:21:in `instrument'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/activesupport-3.0.0/lib/active_support/notifications.rb:52:in `instrument'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0/lib/action_view/render/rendering.rb:56:in `_render_template'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0/lib/action_view/render/rendering.rb:26:in `render'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0/lib/abstract_controller/rendering.rb:114:in `_render_template'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0/lib/abstract_controller/rendering.rb:108:in `render_to_body'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0/lib/abstract_controller/rendering.rb:101:in `render_to_string'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0/lib/abstract_controller/rendering.rb:92:in `render'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionmailer-3.0.0/lib/action_mailer/deprecated_api.rb:111:in `render'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionmailer-3.0.0/lib/action_mailer/old_api.rb:210:in `block in create_parts'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionmailer-3.0.0/lib/action_mailer/old_api.rb:208:in `each'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionmailer-3.0.0/lib/action_mailer/old_api.rb:208:in `create_parts'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionmailer-3.0.0/lib/action_mailer/deprecated_api.rb:143:in `create_parts'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionmailer-3.0.0/lib/action_mailer/old_api.rb:77:in `process'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionmailer-3.0.0/lib/action_mailer/base.rb:446:in `process'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionmailer-3.0.0/lib/action_mailer/base.rb:441:in `initialize'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionmailer-3.0.0/lib/action_mailer/base.rb:425:in `new'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/actionmailer-3.0.0/lib/action_mailer/base.rb:425:in `method_missing'

/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/performable_mailer.rb:6:in `perform'

/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/backend/base.rb:83:in `invoke_job'

/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/worker.rb:119:in `block (2 levels) in run'

/Users/john/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/timeout.rb:57:in `timeout'

/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed
/worker.rb:119:in `block in run'

/Users/john/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/benchmark.rb:309:in `realtime'

/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/worker.rb:118:in `run'

/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/worker.rb:176:in `reserve_and_run_one_job'

/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/worker.rb:103:in `block in work_off'

/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/worker.rb:102:in `times'

/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/worker.rb:102:in `work_off'

/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/worker.rb:77:in `block (2 levels) in start'

/Users/john/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/benchmark.rb:309:in `realtime'

/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/worker.rb:76:in `block in start'

/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/worker.rb:73:in `loop'

/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/worker.rb:73:in `start'

/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/command.rb:100:in `run'

/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/command.rb:79:in `block in run_process'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/daemons-1.1.0/lib/daemons/application.rb:250:in `call'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/daemons-1.1.0/lib/daemons/application.rb:250:in `block in start_proc'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/daemons-1.1.0/lib/daemons/daemonize.rb:199:in `call'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/daemons-1.1.0/lib/daemons/daemonize.rb:199:in `call_as_daemon'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/daemons-1.1.0/lib/daemons/application.rb:254:in `start_proc'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/daemons-1.1.0/lib/daemons/application.rb:294:in `start'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/daemons-1.1.0/lib/daemons/controller.rb:70:in `run'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/daemons-1.1.0/lib/daemons.rb:193:in `block in run_proc'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/daemons-1.1.0/lib/daemons/cmdline.rb:112:in `call'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/daemons-1.1.0/lib/daemons/cmdline.rb:112:in `catch_exceptions'

/Users/john/.rvm/gems/ruby-1.9.2-p0/gems/daemons-1.1.0/lib/daemons.rb:192:in `run_proc'

/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/command.rb:78:in `run_process'

/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/command.rb:72:in `block in daemonize'

/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/command.rb:70:in `times'

/Users/john/.rvm/gems/ruby-1.9.2-p0/bundler/gems/delayed_job-c933ffcd776a/lib/delayed/command.rb:70:in `daemonize'
script/delayed_job:5:in `<main>' |
|improve this question

回答1:


The issue is with the code in your mailer taking the object instead of the objects id:

def contact_mail(contact)
    @contact = contact
    mail(:to => 'my@email.address', :subject => 'Contact Form Query', :from => 'my@email.address', :content_type => 'text/plain')
end

You should change that to this:

def contact_mail(contact_id)
    @contact = Contact.find(contact_id)
    mail(:to => 'my@email.address', :subject => 'Contact Form Query', :from => 'my@email.address', :content_type => 'text/plain')
end

Never pass the actual objects to your mailer. Simply pass the id's and retrieve them upon processing.




回答2:


I had this same problem, and fixed it by moving all the attributes into instance variables. So, in the view:

<%= @contact.name %>
<%= @contact.business %>
<%= @contact.phone %>

becomes:

<%= @name %>
<%= @business %>
<%= @phone %>

and I just looked up the instance variables in the mailer method. So, in the mailer:

def contact_mail(contact)
    @contact = contact
    mail(:to => 'my@email.address', :subject => 'Contact Form Query', :from => 'my@email.address', :content_type => 'text/plain')
end

becomes:

def contact_mail(contact)
    @name = contact.name
    @business = contact.business
    @phone = contact.phone
    mail(:to => 'my@email.address', :subject => 'Contact Form Query', :from => 'my@email.address', :content_type => 'text/plain')
end



回答3:


Why is it not working? Not sure, I imagine it has to do with some ActionMailer voodoo.

How to get it working? Abstract out the delayed job pieces into another class. Have the method that is delayed do nothing more than send them email; meaning that the rendering of the email is done in real time, but the sending of it is delayed. This should get around your problem and accomplish the asynchronous sending of emails.




回答4:


Hey this might be far off, but you're not sending any params to your MAILER. Here's a copy of my referred_email.rb I keep in my lib/ dir. I call it with delayed_job:

#my controller
Delayed::Job.enqueue ReferredEmail.new(params[:subject], params[:editor1])

#Reffered_Email.rb

class ReferredEmail < Struct.new(:subject, :editor1)
  def perform
    (CardReferral.all.map(&:email) - CardSignup.all.map(&:email)).each do |cf|
      @cf = CardReferral.find_by_email(cf)
      Notifier.deliver_referred_magic_email(User.find(@cf.user_id), @cf.email, @cf.name, @cf.message, subject, editor1)
    end
  end
end



回答5:


It seems like you are using both:

  ContactMailer.delay.contact_mail(@contact)

and

  handle_asynchronously :contact_mail, :run_at => Proc.new { 2.seconds.from_now }

which you should only do one or the other. Try removing the handle_asynchronously and see if that fixes the problem.



来源:https://stackoverflow.com/questions/4337879/rails-absolutely-stumped-with-delayed-job-not-receiving-arguments-anywhere

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!