Ruby On Rails:Sidekiq:实例变量@organisation在邮件布局中不可用

ill*_*ist 7 ruby ruby-on-rails redis sidekiq

我已经在后台使用sidekiqredis-server发送电子邮件了.
问题:使用同步方法发送电子邮件时可以.即在...applicants_controller.rb

UserMailer.notify_applicant_assignment(current_assigned_user.id, applicant, workflow_step).deliver
Run Code Online (Sandbox Code Playgroud)

但是,当我使用delay方法发送电子邮件时

applicants_controller.rb

UserMailer.delay.notify_applicant_assignment(current_assigned_user.id, applicant, workflow_step)   
Run Code Online (Sandbox Code Playgroud)

我得到以下错误undefined method 'background_color' for nil:NilClass/layouts/user_mailer.html.erb:17:

代码里面 mailers/user_mailer.rb

class UserMailer < ActionMailer::Base
  include Sidekiq::Worker
  default from: CommonConstants::DO_NOT_REPLY_ADDRESS
  layout 'user_mailer'
    def notify_applicant_assignment(user_id, applicant_id, workflow_step_id)
       @user = User.find(user_id)
       @organization = @user.organization
       @applicant = Applicant.find(applicant_id)
       @url = root_url + 'applicants/' + @applicant.id.to_s
       @workflow_step = WorkflowStep.find(workflow_step_id)
       mail(to: @user.email, subject: 'Applicant Assigned.')
    end
end
Run Code Online (Sandbox Code Playgroud)

代码里面 layouts/user_mailer.html.erb

<body style="background:#f4f4f4;">
<table width="100%" bgcolor="<%= @organization.background_color %>" cellpadding="0" cellspacing="0">
  <tr>
    <td>
      <table align="center" width="730" cellpadding="0" cellspacing="0" >
Run Code Online (Sandbox Code Playgroud)

我在sidekiq控制台遇到错误

2015-03-24T08:58:14Z 5595 TID-cjors WARN: {"retry"=>true, "queue"=>"default", "class"=>"Sidekiq::Extensions::DelayedMailer", "args"=>["---\n- !ruby/class 'UserMailer'\n- :notify_applicant_assignment\n- - 4\n  - '9'\n  - '9'\n"], "jid"=>"4421abf04e7e6864c7ee9fd8", "enqueued_at"=>1427187124.323067, "error_message"=>"undefined method `background_color' for nil:NilClass", "error_class"=>"ActionView::Template::Error", "failed_at"=>1427187124.3466575, "retry_count"=>4, "retried_at"=>1427187494.9246943}
2015-03-24T08:58:14Z 5595 TID-cjors WARN: undefined method `background_color' for nil:NilClass
2015-03-24T08:58:14Z 5595 TID-cjors WARN: /home/leapfrog/projects/ATS/app/views/layouts/user_mailer.html.erb:17:in `_app_views_layouts_user_mailer_html_erb__235114594899105140_70586860'
/home/leapfrog/.rvm/gems/ruby-2.1.1/gems/actionpack-4.0.4/lib/action_view/template.rb:143:in `block in render'
/home/leapfrog/.rvm/gems/ruby-2.1.1/gems/activesupport-4.0.4/lib/active_support/notifications.rb:161:in `instrument'
/home/leapfrog/.rvm/gems/ruby-2.1.1/gems/actionpack-4.0.4/lib/action_view/template.rb:141:in `render'
/home/leapfrog/.rvm/gems/ruby-2.1.1/gems/actionpack-4.0.4/lib/action_view/renderer/template_renderer.rb:61:in `render_with_layout'
/
Run Code Online (Sandbox Code Playgroud)

Mys*_*yst 3

延迟扩展的工作方式很可能与您预期的不同。它们与常规异步作业不同。

文档中,明确指出:

我强烈建议避免在实例上延迟方法。这会在 Redis 中存储对象状态,这些状态可能会过时,从而导致陈旧数据问题。

如果延迟扩展存储未渲染的模板和邮件参数(主题、收件人、发件人等),而不是为过时的实例调用方法本身,我不会感到惊讶。

另外,请注意,尽管Sidekiq 文档声明延迟应应用于类方法,但它notify_applicant_assignment并未定义为类方法(它看起来像实例方法)。

任何方法都可以通过与上面相同的方法延迟:

我建议创建notify_applicant_assignment一个类方法并再次尝试(注意vs.中的self)。def self.notify_applicant_assignmentdef notify_applicant_assignment

class UserMailer < ActionMailer::Base
  include Sidekiq::Worker
  default from: CommonConstants::DO_NOT_REPLY_ADDRESS
  layout 'user_mailer'
    def self.notify_applicant_assignment(user_id, applicant_id, workflow_step_id)
       @user = User.find(user_id)
       @organization = @user.organization
       @applicant = Applicant.find(applicant_id)
       @url = root_url + 'applicants/' + @applicant.id.to_s
       @workflow_step = WorkflowStep.find(workflow_step_id)
       mail(to: @user.email, subject: 'Applicant Assigned.')
    end
end
Run Code Online (Sandbox Code Playgroud)

或者,我建议也使用标准异步引擎applicants_controller.rb

UserMailer.notify_applicant_assignment_async(current_assigned_user.id, applicant, workflow_step)
Run Code Online (Sandbox Code Playgroud)

请让我知道进展如何,以便我可以在需要时进行更多研究。

祝你好运!