Skip to content

Instantly share code, notes, and snippets.

@mikeatlas
Last active April 17, 2022 19:36
Show Gist options
  • Save mikeatlas/5628317 to your computer and use it in GitHub Desktop.
Save mikeatlas/5628317 to your computer and use it in GitHub Desktop.
How to invite users in active admin with devise_invitable
<!-- /app/views/admin/users/new_invitiations.html.erb -->
<h2>Send invitation</h2>
<%= form_for @user, :url => send_invitation_admin_users_path do |f| %>
<table style='width: 50%'>
<tr>
<td><%= f.label :first_name %></td>
<td><%= f.text_field :first_name %></td>
</tr>
<tr>
<td><%= f.label :last_name %></td>
<td><%= f.text_field :last_name %></td>
</tr>
<tr>
<td><%= f.label :email %></td>
<td><%= f.text_field :email, :required => true %></td>
</tr>
</table>
<%= f.submit "Send an Invitation" %>
<% end %>
# /config/routes.rb
devise_for :users,
:controllers => {
:sessions => "users_sessions",
:registrations => "user_registrations",
:passwords => "user_passwords",
# Proper invitations should be sent through the active_admin interface.
:invitations => 'users_invitations' # user_invitations_controller.rb
}
# /app/admin/users.rb
action_item do
link_to 'Invite New User', new_invitation_admin_users_path
end
collection_action :new_invitation do
@user = User.new
end
collection_action :send_invitation, :method => :post do
@user = User.invite!(params[:user], current_user)
if @user.errors.empty?
flash[:success] = "User has been successfully invited."
redirect_to admin_users_path
else
messages = @user.errors.full_messages.map { |msg| msg }.join
flash[:error] = "Error: " + messages
redirect_to new_invitation_admin_users_path
end
end
# /app/controllers/users_invitations_controller.rb
class UsersInvitationsController < Devise::InvitationsController
# GET /resource/invitation/accept?invitation_token=abcdef
def edit
render :edit, :layout => false
end
# PUT /resource/invitation
def update
self.resource = resource_class.accept_invitation!(resource_params)
if resource.errors.empty?
flash_message = resource.active_for_authentication? ? :updated : :updated_not_active
set_flash_message :notice, flash_message
sign_in(resource_name, resource)
redirect_to '/profile', :alert => "Welcome! Please fill out your profile and upload a headshot."
else
respond_with_navigational(resource){ render :edit, :layout => false }
end
end
end
@fletchrichman
Copy link

this is awesome! a few comments:

i only overrode the invitations controller in my implementation, I didn't see the need to override the others.

also, your comments for the file name of the last one is wrong, it should be users_invitations_controller

@mikeatlas
Copy link
Author

@fletchrichman, thanks for the correction, I updated that file.

@andywenk
Copy link

Hi,

I know this is a bit outdated, but I assume it should still work with 1.0.0pre. I thought this is a way to invite AdminUsers but what is shown here is inviting Users so I assume a User model is required. Can I just change User to AdminUser? And why is the content of users.rb not wrapped in a ActiveAdmin.register_page "Users" do ... end block?

Thanks a lot and Cheers

Andy

Copy link

ghost commented Aug 10, 2016

Hi,
If you want to use strong params change this line:
@user = User.invite!(permitted_params[:user], current_user)

@storrence88
Copy link

@andywenk - I think it might just be a snippet. I have my users.rb code in an ActiveAdmin block and it works.

@kerensei - Thanks for the strong params solution! Was trying to figure that one out.

@jelaniwoods
Copy link

This is great and helped me a lot!

I ran into one issue with this part:

collection_action :send_invitation, :method => :post do
  @user = User.invite!(permitted_params[:user], current_user)
  if @user.errors.empty?
    flash[:success] = "User has been successfully invited." 
    redirect_to admin_users_path
  else
    messages = @user.errors.full_messages.map { |msg| msg }.join
    flash[:error] = "Error: " + messages
    redirect_to new_invitation_admin_users_path
  end
end

@user.errors.empty? will probably almost never be true after User.invite! since it skips validations. If you do want to have some validations in the Admin form you can make the blank User with new and call a custom validation method on it before the if. Then if it passes you can save and invite the User.

@user = User.new(permitted_params[:user].merge(invited_by: current_user)
@user.valid_to_invite
if @user.errors.empty?
  @user.save(validate: false)
  @user.deliver_invitation 

@mikeatlas
Copy link
Author

I'm glad a 7 year old gist is still valuable, and appreciate the feedback, @jelaniwoods @storrence88 et al!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment