Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I invite users (using devise_invitable) and populate additional fields during the invite process?

For example, when I go to users/invitations/new, the only field is :email. I'd like to invite a user and, in addition to providing their email, provide:

  • first_name
  • last_name
  • role
  • company (user belongs_to company)

I created Users::InvitationsController < Devise::InvitationsController:

class Users::InvitationsController < Devise::InvitationsController
   private
   def resource_params
     params.permit(user: [:email, :invitation_token, :role, :company_id])[:user]
   end
end

and I added those fields to users/invitations/new. The invitation sends fine, but when I accept it and input a password, my validation fails saying that No role is selected (b/c of a validation).

How can I set these fields before sending the invite and have them persist and save when the invite is accepted? Thanks!

like image 943
jackerman09 Avatar asked Mar 20 '15 18:03

jackerman09


1 Answers

Rails 5

Here is my solution using accepts_nested_attributes_for. If your custom attributes are directly on the user model you should be able to replace profile_attributes: [:first_name, :last_name] with :first_name, :last_name, :role, :company.

Here is my controller.

class InvitationsController < Devise::InvitationsController
  before_action :update_sanitized_params, only: :update

  # PUT /resource/invitation
  def update
    respond_to do |format|
      format.js do
        invitation_token = Devise.token_generator.digest(resource_class, :invitation_token, update_resource_params[:invitation_token])
        self.resource = resource_class.where(invitation_token: invitation_token).first
        resource.skip_password = true
        resource.update_attributes update_resource_params.except(:invitation_token)
      end
      format.html do
        super
      end
    end
  end


  protected

  def update_sanitized_params
    devise_parameter_sanitizer.permit(:accept_invitation, keys: [:password, :password_confirmation, :invitation_token, profile_attributes: [:first_name, :last_name]])
  end
end

Inside my form

<%= f.fields_for :profile do |p| %>
    <div class="form-group">
      <%= p.label :first_name, class: 'sr-only' %>
      <%= p.text_field :first_name, autofocus: true, class: 'form-control', placeholder: 'First name' %>
    </div>

    <div class="form-group">
      <%= p.label :last_name, class: 'sr-only' %>
      <%= p.text_field :last_name, class: 'form-control', placeholder: 'Last name' %>
    </div>
  <% end %>

In user.rb I have

...
accepts_nested_attributes_for :profile, reject_if: proc { |attributes| attributes[:first_name].blank? }
like image 92
Jonathan Bergman Avatar answered Oct 25 '22 00:10

Jonathan Bergman