It adds a module to Devise that allow authenticated resources to send invitations by email to others. Invited resources accept an invitation by setting their password.
Rails 3.0.0.rc and Devise 1.1.1
Use version 0.6.4, add in your Gemfile:
gem "devise", ">= 1.1.1" gem "rymai-devise_invitable", :require => "devise_invitable", :git => "git://github.com/rymai/devise_invitable.git", :branch => "edge"
Rails 3.0.0.beta4 and Devise 1.1.rc2
Use version 0.6.2, add in your Gemfile:
gem "devise", "1.1.rc2" gem "devise_invitable", :git => "git://github.com/rymai/devise_invitable.git", :branch => "rails3"
Follow the walkthrough for Devise with the following modifications.
Add t.invitable to the migration:
create_table :users do ... t.invitable ... end add_index :users, :invitation_token # for invitable
or for a model that is already created, define a migration to add invitable to your model:
change_table :your_table do |t| t.string :invitation_token, :limit => 20 t.datetime :invitation_sent_at t.index :invitation_token # for invitable end # Allow null encrypted_password and password_salt change_column :your_table, :encrypted_password, :string, :null => true change_column :your_table, :password_salt, :string, :null => true
Add :invitable to the Devise line in your model:
class User < ActiveRecord::Base devise ..., :invitable end
If you are using Devise :all, you can add :invitable to config.all in Devise initializer:
Devise.setup do |config| ... config.all = [..., :invitable] ... end
DeviseInvitable adds two new configuration options:
invite_for => It's the time an invitation is valid for. Default value is 0, which means invitation doesn't expire. validate_on_invite => Flag that can force the validation of the invited record on invitation (false by default).
You can set those configuration options in the Devise initializer as follow:
# Time interval where the invitation token is valid. # config.invite_for = 2.weeks # Whether you want to validate the record on a new invite # config.validate_on_invite = true
Sending an invitation
To send an invitation to a user, use the invite class method. You must set email in the parameters hash: You can also include other attributes in the hash. By default, the record will not be validated, see the Model configuration above if you want to validate the records before sending an invitation.
User.invite(:email => "email@example.com", :name => "John Doe") # => an invitation email will be sent to firstname.lastname@example.org
You can also use the invite instance method as follow:
User.new(:email => "email@example.com", :name => "John Doe").invite # => an invitation email will be sent to firstname.lastname@example.org User.find_by_invitation_token("abc123").invite # => an new invitation email will be sent to this user, the generated token will be different
Accepting an invitation
To accept an invitation with a token use the accept_invitation class method. You must set invitation_token in the parameters hash. You can include other attributes in the hash (as in the update_attributes method for example).
User.accept_invitation(:invitation_token => params[:invitation_token], :password => 'abc123')
You can also use the accept_invitation instance method as follow:
invited_user = User.invite(:email => "email@example.com") invited_user.password = '123456' invited_user.accept_invitation
Integration in a Rails application
Since the DeviseInvitable's invitations controller implement the two methods invite and accept_invitation, in most cases you wouldn't call those methods. Instead, in your views, put a link to /users/invitation/new to send an invitation and an email will be sent. This email includes a link to accept the invitation like /users/invitation/accept?invitation_token=abcd123.
It adds authenticate_inviter! filter to restrict who can send invitations. You can override this method in your ApplicationController.
Default behavior requires authentication of the same resource. For example, if your model User is :invitable, it will allow all authenticated users to send invitations to other users.
In a more real scenario you would have a User and Admin models and you would like to allow only admins to send invitations, you could then simply change the authenticate_inviter! method as follow:
module DeviseInvitable module Controllers module Helpers protected def authenticate_inviter! authenticate_admin! end end end end
You have to configure the mailer as it's required for confirmable and recoverable.
DeviseInvitable uses flash messages with I18n with the flash keys :send_instructions and :updated. To customize your app, you can set up your locale file:
en: devise: invitations: send_instructions: 'An email with instructions about how to set the password has been sent.' updated: 'Your password was set successfully. You are now signed in.'
You can also create distinct messages based on the resource you've configured using the singular name given in routes:
en: devise: invitations: user: send_instructions: 'A new user invitation has been sent.' updated: 'Welcome on board! You are now signed in.'
The DeviseInvitable mailer uses the Devise pattern to create subject messages:
en: devise: mailer: invitation_instructions: subject: 'You got an invitation!' user_subject: 'You got an user invitation!'
Take a look at our locale file to check all available messages.
DeviseInvitable supports ActiveRecord and Mongoid, like Devise.
Note on Patches/Pull Requests
Fork the project.
Make your feature addition or bug fix.
Add tests for it. This is important so I don't break it in a future version unintentionally.
Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
Send me a pull request. Bonus points for topic branches.
Maintainer (of this fork)
Rémy Coutable (github.com/rymai)
Based on Sergio Cambra's gem: github.com/scambra/devise_invitable
Check them all at:
Copyright © 2009 Rémy Coutable. See LICENSE for details.