Search code examples
ruby-on-railsdevisedevise-invitable

Devise invitation generate accept_invitation_url


I'm using Devise invitable for invitation. Typically, in the invitation email there will be a link to redirect the invitee to the sign_in page, some url like this

mywebsite.com/users/invitation/accept?invitation_token=J-azZ8fKtkuAyp2VZWQX

This url comes from invitation_instructions.html:

<p><%= link_to 'Accept invitation', accept_invitation_url(@resource, :invitation_token => @token) %></p>

Now I want to return the invitation url in my controller as json response, something like this:

def invite
  invitee = User.invite!({:email => email}, current_user)
  accept_invitation_url = ....
  render :json => accept_invitation_url
end

any idea how to get the accept_invitation_url in the controller? Thanks!


Solution

  • try to include the url helpers module in your controller:

    class MyController < ApplicationController
      include DeviseInvitable::Controllers::UrlHelpers
    
      def invite
        invitee = User.invite!({:email => email}, current_user)
        render :json => accept_invitation_url(invitee, :invitation_token => invitee.token)
      end
    end
    

    The URL Helper module for the Devise Invitable Gem can be found here on github

    Ok the raw invitation token is not accessible by default because it's a instance variable without accessor (source), there are two ways you could solve this.

    The ugly way, without modifying your model class:

      def invite
        invitee = User.invite!({:email => email}, current_user)
        raw_token = invitee.instance_variable_get(:@raw_invitation_token)
        render :json => accept_invitation_url(invitee, :invitation_token => raw_token)
      end
    

    The clean way, by adding an attribute reader to your user model class:

    # User Model
    class User < ActiveRecord::Base
      attr_reader :raw_invitation_token
      # rest of the code
    end
    
    # In your controller
    def invite
      invitee = User.invite!({:email => email}, current_user)
      raw_token = invitee.raw_invitation_token
      render :json => accept_invitation_url(invitee, :invitation_token => raw_token)
    end
    

    Update (16th October 2015):

    It seems like the UrlHelper module has been removed and the invitation is handled as a normal route, so you can remove the include DeviseInvitable::Controllers::UrlHelpers and replace the accept_invitation_url call with:

    Rails.application.routes.url_helpers.accept_invitation_url(invitee, :invitation_token => raw_token)