A common way to add custom behavior after user login is to subclass Devise’s SessionsController and override the necessary actions. This approach is flexible and keeps the custom logic separate from the Devise setup.
1. Update your routes to point to the custom sessions controller:
# config/routes.rb
devise_for :users, controllers: { sessions: "custom_sessions" }
2. Create a new sessions controller:
# app/controllers/custom_sessions_controller.rb
class CustomSessionsController < Devise::SessionsController
before_action :before_login, only: :create
after_action :after_login, only: :create
private
def before_login
# Add custom logic to execute before login (optional).
end
def after_login
# Add custom logic to execute after login, e.g., creating a directory.
create_user_directory unless directory_exists?
end
def create_user_directory
# Example implementation
user_dir = Rails.root.join("user_data", current_user.username)
FileUtils.mkdir_p(user_dir) unless Dir.exist?(user_dir)
end
def directory_exists?
Dir.exist?(Rails.root.join("user_data", current_user.username))
end
end
3. Test the changes by logging in and verifying that the custom code is executed.
Devise is built on top of Warden, which provides callbacks to execute code during authentication events. This approach integrates directly into Devise's lifecycle without overriding controllers.
1. Add the Warden callback in devise.rb:
# config/initializers/devise.rb
Warden::Manager.after_authentication do |user, auth, opts|
# Custom logic after login
Rails.logger.info "User #{user.email} logged in at #{Time.now}"
# Check and create directory for the user
user_dir = Rails.root.join("user_data", user.username)
FileUtils.mkdir_p(user_dir) unless Dir.exist?(user_dir)
end
2. Restart your Rails server to apply the changes.
Notes:
Another approach is to hook into Rails’ ActiveSupport::Notifications to handle post-login events. This keeps the custom logic modular and independent of Devise’s implementation.
1. Add the notification in sessions_controller.rb:
# app/controllers/custom_sessions_controller.rb
class CustomSessionsController < Devise::SessionsController
after_action :notify_login_event, only: :create
private
def notify_login_event
ActiveSupport::Notifications.instrument("user.logged_in", user: current_user)
end
end
2. Create a subscriber for the event:
# config/initializers/login_subscriber.rb
ActiveSupport::Notifications.subscribe("user.logged_in") do |name, start, finish, id, payload|
user = payload[:user]
Rails.logger.info "User #{user.email} logged in!"
# Check and create directory for the user
user_dir = Rails.root.join("user_data", user.username)
FileUtils.mkdir_p(user_dir) unless Dir.exist?(user_dir)
end
Devise provides built-in hooks like after_sign_in_path_for that can be customized to execute specific logic.
1. Override after_sign_in_path_for in ApplicationController
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
protected
def after_sign_in_path_for(resource)
# Custom logic after login
create_user_directory(resource) unless directory_exists?(resource)
super
end
private
def create_user_directory(user)
user_dir = Rails.root.join("user_data", user.username)
FileUtils.mkdir_p(user_dir) unless Dir.exist?(user_dir)
end
def directory_exists?(user)
Dir.exist?(Rails.root.join("user_data", user.username))
end
end
2. This method allows you to handle logic seamlessly after login without altering session controllers or Warden directly:
Each approach serves a unique purpose based on your app's structure and needs:
Test each solution and choose the one that aligns best with your application's architecture and maintenance strategy.
Work with our skilled Ruby on Rails developers to accelerate your project and boost its performance.
Hire Ruby on Rails Developer