Search code examples
ruby-on-railsruby-on-rails-4sidekiq

How to pass data to an email template that is sent via Sidekiq


I'm using Rails, Mongoid and Sidekiq in this app.

In my Mailer I have the following:

def send_invoice(invoice, domain)
  @invoice = Invoice.find(invoice)
  @user = User.find(domain)
  attachments["invoice.pdf"] = File.read("#{Rails.root}/invoices/pdf/55f5c596019e2b51af000000-55f82b520540a78f43000000.pdf")
  mail to: "[email protected]", subject: "Invoice from MyJarvis", reply_to: @user.email, :from => @user.email, :bcc => '[email protected]'
end

And in my email template I have something like this (haml):

!!!
%html
  = "Hello #{@invoice[:name]}"

And if I use ActiveMailer (not using Sidekiq) all works fine. Now in my worker:

def perform(data, count)
  message = JSON.load(data)
  UserMailer.send_invoice(message['invoice'], message['domain']).deliver
end

Then I get an error saying ActionView::Template::Error: undefined method '[]' for nil:NilClass

After some investigation I found out that the problem is with the variable used in the email. When I tried the same email without using the variable, all worked fine.

Now I understand this is an issue on how Sidekiq stores data in Redis (as json). What I don't know is, how can I pass variables to the email template using Sidekiq?

EDIT: Here's my Mailer and my Worker:

Mailer:

def send_invoice(invoice, domain)
  @invoice = Invoice.find(invoice)
  @user = User.find(domain)
  attachments["invoice.pdf"] = File.read("#{Rails.root}/invoices/pdf/55f5c596019e2b51af000000-55f82b520540a78f43000000.pdf")
  mail to: "[email protected]", subject: "Invoice", reply_to: @user.email, :from => @user.email
end

Worker:

def perform(data, count)
  message = JSON.load(data)
  UserMailer.send_invoice(message['invoice'], message['domain']).deliver
end

And in my controller:

...
h = JSON.generate({ 'invoice' => @invoice.id.to_s, 'domain' => set_db })
PostmanWorker.perform_async(h, 1)
...

So as you can see I'm passing the id for it to be processed inside the worker rather than passing a Hash. But how can I pass the @invoice hash to the email template?


Solution

  • According to the docs (https://github.com/mperham/sidekiq/wiki/Active-Job), there is a newer syntax (API) for delivering email:

    UserMailer.welcome_email(@user).deliver_later!(wait: 1.hour)
    

    Checkout the section under "Action Mailer", as that may solve your problem.