Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pass extra instance vars to devise_invitable email template

I'm overriding the devise_invitable controller and in my create method I'd like to pass extra values to the invitations_instructions email template. For example group name, has anyone been successful at this, if so please give me some clues here.

what I've tried...

my @group in my Users::InvitesController < Devise::InvitationsController create method is undefined in the email template.

tried to add :skip_invitation => true in my create and then send the email manually like...

self.resource = resource_class.invite!(params[resource_name], current_inviter, :skip_invitation => true)
 ::Devise.mailer.invitation_instructions(self.resource).deliver

but this gives the wrong number of arguments so there is something I'm not reading correctly from the documentation.

UPDATE - possible solution

The only way appears to be this, but I'm curious if there is a better way that uses the templates provided and devise mailer

in my /app/controller/users/InvitesController#create (inherits from InvitationsController)

self.resource = resource_class.invite!(params[resource_name], current_inviter) do |u|
  u.skip_invitation = true
end
UserMailer.invitation_instructions(self.resource, current_inviter, @object).deliver

where UserMailer is my general (standard) action mailer and goes something like...

def invitation_instructions(resource, inviter, object)
    @resource = resource
    @object = object
    @inviter = inviter

    mail(:to => resource.email, :subject => 'New invitation from ' + inviter.first_name)
  end
like image 418
Andrew Lank Avatar asked Oct 04 '11 13:10

Andrew Lank


1 Answers

There is a cleaner way to achieve the solution that you're looking for, and that is to use Devise's own procedures for overriding mailer templates.

First create a custom mailer that extends from Devise::Mailer:

class MyMailer < Devise::Mailer   
  helper :application # gives access to all helpers defined within `application_helper`.
  include Devise::Controllers::UrlHelpers # Optional. eg. `confirmation_url`
  default template_path: 'devise/mailer' # to make sure that your mailer uses the devise views
end

Then, in config/initializers/devise.rb, set config.mailer to "MyMailer". This is going to allow you to override ANY email that devise sends out and customize to your liking.

Then for you, you can override invitable_instructions like this:

def invitation_instructions(record, token, opts={})
  # Determine a way to set object -- likely through a query of some type
  @object = get_object_for(record)

  opts[:subject] = 'New invitation from ' + inviter.first_name

  super
end

The main sticking point from your example was passing in extra data to set @group/@object. To do that, I would personally go with some type of query within the mailer (not clean, but it is encapsulated and therefore less "magical") to retrieve those objects.

Additionally, if you wanted to use custom email templates instead of devise's, you can simply add them to the app/views/my_mailer/ directory and devise will prefer emails in that directory over emails from the gem.

like image 122
Gavin Miller Avatar answered Oct 20 '22 04:10

Gavin Miller