How To Create Invitations From Any Model with Devise Invitable

Chris Oliver

May 5, 2014

A really useful extenison to the Devise authentication gem is devise_invitable. It adds invitation functionality that can be used for building a referral system or just general email invitations to your web app.

The way it is works is extremely simple. It just adds a invite! method to the model and you can pass in attributes just like calling create.

User.invite!(email: "", name: "John Doe")

This is great, and it automatically keeps track of which user sent the invitation if you pass that object in:

User.invite!({:email => ""}, current_user)
# current_user will be set as invited_by

This is great for keeping track of who invited who, but this also requires the Inviter to have a few methods. These methods are basic helpers that devise_invitable has for extra configuration options like limiting the number of invitations a user can send out.

What happens when you want to invite a user from a different model that isn't devise_invitable though? It breaks!

Let's take this for example: We have AdminUsers which we definitely don't want created by invitations but we want them to be able to invite Users and track that an AdminUser invited them.

If you try this without adding devise_invitable to AdminUser, you'll get an error similar to these two errors: undefined methodhas_invitations_left?' for #AdminUser:0x102e98948andNameError (undefined local variable or method invitation_token' for #<AdminUser:0x0000010334baa8>):

The AdminUser model doesn't have the fields that devise_invitable requires so it crashes.

The fix is simple. We can include a module on the models that are inviting Users without adding devise_invitable:

class AdminUser < ActiveRecord::Base
  include DeviseInvitable::Inviter

P.S. You might enjoy following me on Twitter.