← Back to list

Overcoming Devise and ActiveAdmin 2FA Issues After Upgrading to Ruby 3.2.1 and Rails 7

When upgrading legacy applications to modern frameworks and languages, developers often encounter challenges that test their…

YUVRAJ SINGH · 2024-11-19 08:53 · 0 claps · 2.3 min read
#ruby #rails #active-admin #ruby-on-rails #devise-gem
Open on Medium ↗
Wiki topics: 🌐 · Web Development

Overcoming Devise and ActiveAdmin 2FA Issues After Upgrading to Ruby 3.2.1 and Rails 7

When upgrading legacy applications to modern frameworks and languages, developers often encounter challenges that test their problem-solving skills and perseverance. Recently, I faced such an issue while upgrading my Ruby and Rails versions. Here’s my story of how I tackled a NameError with Devise and ActiveAdmin during a Rails upgrade and successfully restored 2FA functionality for admin logins.

The Context: Pre-Upgrade Setup

In my Rails application, I had implemented a two-factor authentication (2FA) mechanism for admin users using ActiveAdmin and Devise. To achieve this, I overrode the default ActiveAdmin Devise SessionsController with custom logic that generated and verified OTPs for each admin login attempt. Here’s the relevant code:

class ActiveAdmin::Devise::SessionsController
  include ::ActiveAdmin::Devise::Controller

  def create
    super do |resource|
      # Generate and save OTP
      resource.generate_and_save_otp
      puts "Mobile Verification code for admin login is #{resource.mobile_otp}"
      redirect_to admin_otp_verification_path(resource_id: resource.id) and return if resource.mobile_otp.present?
    end
  end

This code worked seamlessly with my previous versions of Ruby and Rails, providing enhanced security through 2FA for admin users.

The Issue: Upgrading to Ruby 3.2.1 and Rails 7

With an upgrade to Ruby 3.2.1 and Rails 7, everything seemed fine at first, until I encountered a NameError during rake assets:precompile: or rails c or rails s

rake aborted!
NameError: uninitialized constant Devise::SessionsController (NameError)

    class SessionsController < ::Devise::SessionsController

Initial Attempts at a Solution

Like many developers, my first instinct was to troubleshoot using common approaches:

  • Double-checking gem versions and compatibility
  • Searching online for existing solutions
  • Using Chat GPT and other AI tools
  • Experimenting with different configurations

Unfortunately, none of the suggested fixes worked, and my frustration grew as I realized that the community seemed to have little information on this specific issue.

The Breakthrough: Diving Into ActiveAdmin’s Codebase

Determined to get to the root of the problem, I decided to examine the latest code for ActiveAdmin on GitHub. This led me to a critical discovery in lib/active_admin/devise.rb, which handles Devise configurations for ActiveAdmin:

module ActiveAdmin
  module Devise
    # ...
    class SessionsController < ::Devise::SessionsController
      include ::ActiveAdmin::Devise::Controller

      ActiveSupport.run_load_hooks(:active_admin_controller, self)
    end
    # ...
  end
end

Here, I realized that recent changes in ActiveAdmin and Devise’s internal handling of controllers required adjustments to the way custom controllers were configured.

The Solution: Updating Routes and Custom Controller Configuration

To resolve the issue, I merged my custom sessions controller logic with ActiveAdmin’s Devise configuration. Here’s how I modified my custom sessions controller and routes file

# app/controllers/admin/custom_sessions_controller.rb
module Admin
  class CustomSessionsController < ActiveAdmin::Devise::SessionsController
    include ::ActiveAdmin::Devise::Controller

    def create
      super do |resource|
        # Generate and save OTP
        resource.generate_and_save_otp
        puts "Mobile Verification code for admin login is #{resource.mobile_otp}"
        if resource.mobile_otp.present?
          redirect_to admin_otp_verification_path(resource_id: resource.id) and return
        end
      end
    end
  end
end
# config/routes.rb

# Merging custom sessions controller configuration with ActiveAdmin's Devise config
custom_config = ActiveAdmin::Devise.config.merge(
  controllers: { sessions: 'admin/custom_sessions' }
)

devise_for :admin_users, custom_config
ActiveAdmin.routes(self)

This approach ensures that my custom 2FA logic remains functional while maintaining compatibility with newer versions of ActiveAdmin and Devise.

Key Takeaways

  1. Understand Internal Changes: Updates to major libraries like Devise and ActiveAdmin can introduce breaking changes. Reviewing their code and changelogs can provide critical insights.
  2. Consolidate Configuration: Merging custom configurations with library-provided defaults can prevent conflicts and unexpected behaviors.
  3. Persistence Pays Off: Troubleshooting complex upgrade issues requires patience and a willingness to explore less-documented areas.

Final Thoughts

With these changes, my Rails application now fully supports Ruby 3.2.1 and Rails 7, while continuing to provide secure 2FA for admin users. I hope this write-up helps others facing similar challenges. If you’ve encountered similar issues or have other tips to share, please leave a comment below!

class SessionsController < ::Devise::SessionsController


메타데이터
post_id
7cfdb6a3c57b
slug
overcoming-devise-and-activeadmin-2fa-issues-after-upgrading-to-ruby-3-2-1-and-rails-7-7cfdb6a3c57b
url
https://medium.com/@jarvuy7/overcoming-devise-and-activeadmin-2fa-issues-after-upgrading-to-ruby-3-2-1-and-rails-7-7cfdb6a3c57b
canonical_url
https://medium.com/@jarvuy7/overcoming-devise-and-activeadmin-2fa-issues-after-upgrading-to-ruby-3-2-1-and-rails-7-7cfdb6a3c57b
author_url
https://medium.com/@jarvuy7
status
ok
fetched_at
2026-08-11 21:02:09