Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails - How to override devise SessionsController to perform specific tasks when user signs in?

Using Devise to manage users sessions / registrations I would need to perform specific tasks (updating some fields in the users table for this specific user for example) each time a user signs in, and before he gets redirected by devise to the home page for connected users.

Do I have to override devise SessionsController, and if yes, how?

like image 552
Patrice Navarre Avatar asked Dec 12 '12 08:12

Patrice Navarre


3 Answers

Alternatively, you can create your own sessions controller

class SessionsController < Devise::SessionsController
  def new
    super
  end

  def create
    self.resource = warden.authenticate!(auth_options)
    set_flash_message(:notice, :signed_in) if is_navigational_format?
    sign_in(resource_name, resource)
    if !session[:return_to].blank?
      redirect_to session[:return_to]
      session[:return_to] = nil
    else
      respond_with resource, :location => after_sign_in_path_for(resource)
    end
  end
end

And in routes.rb add:

devise_for :users, controllers: {sessions: "sessions"}
like image 123
Pykih Avatar answered Nov 13 '22 17:11

Pykih


If you look at Devise's implementation of sessions_controller#create, you'll notice that they yield if you pass a block.

So, just subclass their sessions controllers and pass a block when you call super. To do that, first tell Devise in routes.rb that you'd like to use your own sessions controller:

devise_for :users, controllers: { sessions: 'users/sessions' }

And then create a SessionsController class and pass a block when you call super in your create method. It would look something like this:

# app/controllers/users/sessions_controller.rb

class Users::SessionsController < Devise::SessionsController
  layout "application"
  
  # POST /login
  def create
    super do |user|
      if user.persisted?
        user.update(foo: :bar)
      end
    end
  end
end

Most of the Devise controller methods accept a block, so you could do this for registration, forgot password, etc as well.

like image 33
stephen.hanson Avatar answered Nov 13 '22 18:11

stephen.hanson


Devise provides after_database_authentication callback method.You have full access for the current authenticated user object over there.

If you want to update current user name after every successful login you can do that like below.

class User < ActiveRecord::Base
  devise :database_authenticatable

  def after_database_authentication
    self.update_attributes(:name => "your name goes here")
  end 
end
like image 20
Soundar Rathinasamy Avatar answered Nov 13 '22 18:11

Soundar Rathinasamy