Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using devise_invitable for adding Users to a Group in Ruby on Rails?

I have a "Groups" resource within my app that Users can join (a Group has_and_belongs_to_many Users and vice versa). The devise_invitable plugin allows an existing User on my app to email an invitation to another poetntial User to register on the site, but I want some extra functionality: I want a User to be able to invite someone to a particular Group, so that as soon as they accept that invitation in the email, they can see a link to join that Group.

Has anyone used devise_invitable to do something like this? What's the best way to go about adding this extra functionality? It seems I'd need to include some sort of of "Group token" identifying the Group in the invite email, then pass it back in the URL that the user clicks to accept the invite.

Should I be overriding the invitations controller methods, or is there another plugin that serves the purpose better?

like image 783
Tim Avatar asked Nov 11 '10 21:11

Tim


2 Answers

I have just implemented some very similar. I have tried to use devise_invitable but it was to much work. So I looked for some other plugins but I could not find anything and I concluded it was just easier to write my own implementation. This is what I did:

  • adding a invitation resource,

  • when a user create an invitation I store in an invitation field (it is a serialized hash) all the info I need to apply to the user that will accept the invitation

  • an email is sent out to the invited user, it contains a link like: /users/signup?invitation_token=1231223123

  • when user clicks on the link I create the user and applies all the info stored in the invitation like group membership, name, roles...

  • if the invited user does not need to signup for the service than the link in the email is different: invitations/123/accept?invitation_token=12312312asdas324

Hope this help

like image 106
Matteo Melani Avatar answered Nov 20 '22 05:11

Matteo Melani


I've done this by overriding the invites controller, the instructions to do this are in the devise_invitable main page on github so I won't go into it here.

For security, I created a new table that holds extra invitation information so that the email accept link does not hold the group link (my groups are by private invites only so I don't want a invited user to alter the invite url in the email and potentially add other groups which they were not invited).

The new table is indexed by the user id after devise_invitable creates it in the user table.

class Users::InvitesController < Devise::InvitationsController
.
.
def create

    # make sure the current user is connected to this object for security
    if @object.has_connection_with(current_user)

      # perform the invite    
      self.resource = resource_class.invite!(params[resource_name], current_inviter)

      #since we invite based on object, we must reference this object once the user accepts, so we store this in our Invites table
      object_invite = Invite.new(:invitable_type => @object.class.name, :invitable_id => @object.id, :user_id => self.resource.id, :inviter_id => current_inviter.profile.id)
      object_invite.save!

      if resource.errors.empty?
        set_flash_message :notice, :send_instructions, :email => self.resource.email
        #respond_with resource, :location => after_invite_path_for(resource)
        render :json => {:status => 'success'} and return
      else
        respond_with_navigational(resource) { render_with_scope :new }
      end
    end
  end

Then in your update method (again in the same controller) you can find() the Invites record and pull the required info that will allow you to connect the new user to the group.

The only issue left is how to add additional parameters to the email, like group name, which I have yet to resolve.

like image 42
Andrew Lank Avatar answered Nov 20 '22 06:11

Andrew Lank