-
Notifications
You must be signed in to change notification settings - Fork 553
Invite a Resource (or User) that Has Already Signed Up without Invitation
DeviseInvitable provides a mechanism for re-sending invitations to users who have already been invited.
In my case, I wanted to invite an existing User
because the invitation associates a generic user with an "admin" user, who controls the "team" and manages payment info for all invited users.
If you'd like to send an invitation to a user that has already signed up, but has not been invited (in other words, they signed up on their own), then you'll need to customize DeviseInvitable's behavior.
You'll want to add that new logic to either your InvitationsController
's #create
action or to the protected method, invite_resource
, by overriding one of the methods (as recommended in the README section on Configuring Controllers).
Below is an example implementation. I've decided to add the new logic in the invite_resource
method instead of the #create
action.
The new logic checks if a user already exists with the submitted email address (invite_params[:email]
). It also prevents a user from sending an invitation to their own email address.
Notice that the devise_invitable
's invite_resource
method returns an instance of a resource
class, or in this example, a User
instance (@user
). The invite!
class method returns an instance of a resource
class, but the invite!
instance method returns a Mail::Message
object. It's easy to overlook that difference in return type. Adding the new logic to the invite_resource
method ensures that the create action behaves the same regardless of whether the resource
is a new or existing User
.
class Users::InvitationsController < Devise::InvitationsController
protected
# invite_resource is called when creating invitation
# should return an instance of resource class
# this is devise_invitable's implementation
# def invite_resource(&block)
# resource_class.invite!(invite_params, current_inviter, &block)
# end
def invite_resource(&block)
@user = User.find_by(email: invite_params[:email])
# @user is an instance or nil
if @user && @user.email != current_user.email
# invite! instance method returns a Mail::Message instance
@user.invite!(current_user)
# return the user instance to match expected return type
@user
else
# invite! class method returns invitable var, which is a User instance
resource_class.invite!(invite_params, current_inviter, &block)
end
end
end