ruby-on-railssidekiqruby-on-rails-4.1mailboxer

How can I get Sidekiq to work with Mailboxer message emails?


I'm on Rails 4.1 trying to work with the Mailboxer Gem and Sidekiq, and I followed along with the documentation and the sample app in the docs to set everything up. Then I configured the mailers to use UserMailer with this in the initializers/mailboxer.rb:

config.notification_mailer = UserMailer
config.message_mailer = UserMailer

Everything works pretty much as expected, both on the site and receiving emails when messages are sent or replied to. Next, I tried to have the mail jobs done asynchronous using Sidekiq using this code I got from one of the issues on the Mailboxer github page. This also is in the initializer:

config.custom_deliver_proc = ->(mailer, mailable, recipient) do
  mailer.delay.send_email(mailable, recipient)
end

However, now when I send a message, it hits Sidekiq but it throws this error:

ArgumentError: undefined class/module Mailboxer::Message

Here's the relevant code in user_mailer.rb:

def send_email(message, receiver)
  if message.conversation.messages.size > 1
    reply_message_email(message,receiver)
  else
    new_message_email(message,receiver)
  end
end

#Sends an email for indicating a new message for the receiver
def new_message_email(message,receiver)
  @message  = message
  @receiver = receiver
  set_subject(message)
  mail :to => receiver.send(Mailboxer.email_method, message),
     :subject => t('mailboxer.message_mailer.subject_new', :subject => @subject),
     :template_name => 'new_message_email'
end

#Sends and email for indicating a reply in an already created conversation
def reply_message_email(message,receiver)
  @message  = message
  @receiver = receiver
  set_subject(message)
  mail :to => receiver.send(Mailboxer.email_method, message),
     :subject => t('mailboxer.message_mailer.subject_reply', :subject => @subject),
     :template_name => 'reply_message_email'
end

I'm not currently using notifications so I haven't included that. Where is it calling Mailboxer::Message, and what arguments does it expect? Is this a Rails 4.1 thing? I'm still pretty new to Ruby/Rails, sorry if this is an obvious error on my part.

I also tried calling delay on the individual methods in UserMailer, with the same result:

def send_email(message, receiver)
  if message.conversation.messages.size > 1
    UserMailer.delay.reply_message_email(message,receiver)
  else
    UserMailer.delay.new_message_email(message,receiver)
  end
end

Solution

  • UPDATE: The syntax changed in Rails 4.2 and above. See Tomasz's answer below for new syntax.


    We upgraded to Rails 4.1.4 and I tried the same code again and it worked this time. I put

    config.custom_deliver_proc = ->(mailer, mailable, recipient) do
      mailer.delay.send_email(mailable, recipient)
    end
    

    at the end of the initializer, not sure if the placement makes a difference.

    I'm still not exactly sure why the same code works now and didn't before, but my theory is that this was a Rails 4.1.0 issue that was fixed with the 4.1.4 upgrade. Hope this helps someone else!