Prashanth
Prashanth

Reputation: 347

Override devise create controller action

I am creating an app(User has many groups) in which an existing user can send invitations to invite people to join a group. If the sign_up url has an invitation token I need to override the default devise controller action for create.

routes.rb

devise_for :users do 
  match '/users/sign_out', :to => 'devise/sessions#destroy'
  match '/users/sign_up/:invitation_token', :to => 'registrations#create'

registrations_controller.rb

class RegistrationsController < Devise::RegistrationsController
#after_filter :add_user_to_group

def new
    super
end

def create
  if !params[:invitation_token].nil?
    token = params[:invitation_token]
    @invitation = Invitation.where "token" => token 
      if [email protected]?
            build_resource
            if resource.save
              if resource.active_for_authentication?
                set_flash_message :notice, :signed_up if is_navigational_format?
                sign_up(resource_name, resource)
                respond_with resource, :location => after_sign_up_path_for(resource)
              else
                set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_navigational_format?
                expire_session_data_after_sign_in!
                respond_with resource, :location => after_inactive_sign_up_path_for(resource)
               end
             else
               clean_up_passwords resource
               respond_with resource
             end
    else
      flash[:notice] = "Invalid Token. Cannot signup with this Link." 
    end
  else
    super
  end
end

def after_sign_up_path_for(resource_or_scope)
  @user = current_user
  raise @user.inspect
  @invitation = Invitation.where "recipient_email" => @user.email
  if [email protected]?
    @user.update_attribute(:invitation_id, @invitation.id)
    @user_group = UserGroup.new
    @user_group.user_id = @user.id
    @userGroup.group_id = @invitation.group_id
    @userGroup.save!  
  end
  after_sign_in_path_for(resource)
end

end

Logs

Started GET "/users/sign_up/83003a4fab004ef4c1934c15f7215e8dc6a57718" for 127.0.0.1 at 2012-12-11 14:53:18
Processing by RegistrationsController#create as HTML
  Parameters: {"invitation_token"=>"83003a4fab004ef4c1934c15f7215e8dc6a57718"}
  SQL (0.1ms)  BEGIN
  User Exists (1.0ms)  SELECT 1 AS one FROM `users` WHERE `users`.`name` IS NULL LIMIT 1
  User Exists (0.1ms)  SELECT 1 AS one FROM `users` WHERE `users`.`email` = '' LIMIT 1
   (0.1ms)  ROLLBACK

This redirects me to the sign_up path but carries out the validations on page load.

Email can't be blank
Password can't be blank
Name can't be blank

Logs after sign_up wit the page rendered earlier

Started POST "/users" for 127.0.0.1 at 2012-12-11 14:56:37 +0530
Processing by Devise::RegistrationsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"gUmNDb1Sj/ZVnXMG8t/Av0QlAYg7nAMTsSU5ZBW+s60=", "user"=>{"name"=>"Prashanth2", "email"=>"[email protected]", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Sign up"}
  SQL (0.1ms)  BEGIN
  User Exists (0.4ms)  SELECT 1 AS one FROM `users` WHERE `users`.`email` = BINARY '[email protected]' LIMIT 1
  User Exists (0.3ms)  SELECT 1 AS one FROM `users` WHERE `users`.`name` = 'Prashanth2' LIMIT 1
  User Exists (0.2ms)  SELECT 1 AS one FROM `users` WHERE `users`.`email` = '[email protected]' LIMIT 1
  SQL (1.1ms)  INSERT INTO `users` (`created_at`, `current_sign_in_at`, `current_sign_in_ip`, `email`, `encrypted_password`, `invitation_id`, `invitation_limit`, `last_sign_in_at`, `last_sign_in_ip`, `name`, `remember_created_at`, `reset_password_sent_at`, `reset_password_token`, `sign_in_count`, `updated_at`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)  [["created_at", Tue, 11 Dec 2012 09:26:37 UTC +00:00], ["current_sign_in_at", nil], ["current_sign_in_ip", nil], ["email", "[email protected]"], ["encrypted_password", "$2a$10$jcaLbYWNqp2sbUlAZWb38.Ls7Ku90ImOQ11k0fxJSq/mD4Zm2U1JO"], ["invitation_id", nil], ["invitation_limit", 5], ["last_sign_in_at", nil], ["last_sign_in_ip", nil], ["name", "Prashanth2"], ["remember_created_at", nil], ["reset_password_sent_at", nil], ["reset_password_token", nil], ["sign_in_count", 0], ["updated_at", Tue, 11 Dec 2012 09:26:37 UTC +00:00]]
   (108.5ms)  COMMIT
  SQL (0.1ms)  BEGIN
   (0.3ms)  UPDATE `users` SET `last_sign_in_at` = '2012-12-11 09:26:38', `current_sign_in_at` = '2012-12-11 09:26:38', `last_sign_in_ip` = '127.0.0.1', `current_sign_in_ip` = '127.0.0.1', `sign_in_count` = 1, `updated_at` = '2012-12-11 09:26:38' WHERE `users`.`id` = 12
   (127.8ms)  COMMIT

Upvotes: 4

Views: 2395

Answers (2)

barnaclebarnes
barnaclebarnes

Reputation: 366

I had to do a similar thing. I ended up adding the code for adding the token to user model and having a separate controller action to accept invitations:

user.rb

after_create :accept_invitation, if: :token

private
  def accept_invitation
    # Or whatever you need to add the invitation token.
    permission = Permission.find_by_token(token)
    if permission
      permission.update_attributes!(user_id: id, accepted: true) 
      UserMailer.admin_accepted_invitation_email(permission).deliver
    end
  end

registrations_controller.rb

class Users::RegistrationsController < Devise::RegistrationsController
  layout "home"

  def accept_invitation
  @invitation = Permission.find_by_token!(params[:token])
  @user = User.new(token: @invitation.token)
end
end

Upvotes: 1

Arpit Vaishnav
Arpit Vaishnav

Reputation: 4780

Please follow the link for registration without password

Registration without password :: device

Upvotes: 0

Related Questions