Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Devise UninitializedConstant ApplicationController with controllers in subfolder

I'm trying to consolidate one of my apps to controllers and views into sub folders - one for the marketing site, and one for the app itself.

This is what I currently have:

app/controllers
  application_controller.rb
  ...shit ton of other controllers...

This is what i'm going for:

app/controllers/app
  application_controller.rb
  ...all controllers related to the app itself...

app/controllers/marketing
  ...all controllers related to the marketing site...

Marketing site works just fine because there is no authentication necessary, but the app is bombing out b/c devise doesn't know that application_controller.rb is now in app/controllers/app/application_controller.rb

How can I tell devise about the location of my controller?

Here's my devise routes:

devise_for :users, :skip => [:sessions]
      as :user do
        get 'login' => 'devise/sessions#new', :as => :new_user_session
        post 'login' => 'devise/sessions#create', :as => :user_session
        delete 'logout' => 'devise/sessions#destroy', :as => :destroy_user_session
        get 'logout' => 'devise/sessions#destroy', :as => :destroy_user_session
      end

Part of the stacktrace:

NameError - uninitialized constant ApplicationController:
  activesupport (3.2.12) lib/active_support/dependencies.rb:520:in `load_missing_constant'
  activesupport (3.2.12) lib/active_support/dependencies.rb:192:in `block in const_missing'
  activesupport (3.2.12) lib/active_support/dependencies.rb:190:in `const_missing'
  activesupport (3.2.12) lib/active_support/inflector/methods.rb:230:in `block in constantize'
  activesupport (3.2.12) lib/active_support/inflector/methods.rb:229:in `constantize'
  activesupport (3.2.12) lib/active_support/core_ext/string/inflections.rb:54:in `constantize'
  devise (2.2.4) app/controllers/devise_controller.rb:2:in `<top (required)>'
  activesupport (3.2.12) lib/active_support/dependencies.rb:469:in `block in load_file'
  activesupport (3.2.12) lib/active_support/dependencies.rb:639:in `new_constants_in'
  activesupport (3.2.12) lib/active_support/dependencies.rb:468:in `load_file'
  activesupport (3.2.12) lib/active_support/dependencies.rb:353:in `require_or_load'
  activesupport (3.2.12) lib/active_support/dependencies.rb:502:in `load_missing_constant'
  activesupport (3.2.12) lib/active_support/dependencies.rb:192:in `block in const_missing'
  activesupport (3.2.12) lib/active_support/dependencies.rb:190:in `const_missing'
  activesupport (3.2.12) lib/active_support/dependencies.rb:514:in `load_missing_constant'
  activesupport (3.2.12) lib/active_support/dependencies.rb:192:in `block in const_missing'
  activesupport (3.2.12) lib/active_support/dependencies.rb:190:in `const_missing'
  activesupport (3.2.12) lib/active_support/dependencies.rb:514:in `load_missing_constant'
  activesupport (3.2.12) lib/active_support/dependencies.rb:192:in `block in const_missing'
  activesupport (3.2.12) lib/active_support/dependencies.rb:190:in `const_missing'
  activesupport (3.2.12) lib/active_support/dependencies.rb:514:in `load_missing_constant'
  activesupport (3.2.12) lib/active_support/dependencies.rb:192:in `block in const_missing'
  activesupport (3.2.12) lib/active_support/dependencies.rb:190:in `const_missing'
  devise (2.2.4) lib/devise/controllers/helpers.rb:80:in `devise_controller?'
  devise (2.2.4) lib/devise/controllers/helpers.rb:48:in `authenticate_user!'
like image 854
Catfish Avatar asked Jan 29 '26 11:01

Catfish


2 Answers

As @benchwarmer said, if you do put a controller in a subdirectory, you'll need to namespace the class name accordingly; App::ApplicationController in your case. However, it seems you'd then need to make all your existing controllers inherit from App::ApplicationController instead of ApplicationController. Why not keep ApplicationController at the top level and if you need additional methods for the main app or the marketing app, create, for example, a Marketing::MarketingController in marketing/ which extends ApplicationController and which all controllers in marketing can then extend, and similarly for the app directory. Alternatively, you could just put your marketing controllers in a marketing subdirectory and Marketing:: namespace, and leave your app controllers in controllers/ instead of having a separate subdirectory for them. Anyway, up to you. The other piece of the puzzle is that if you move the ApplicationController (or want devise to inherit from any arbitrary controller), you'll need to add to your devise.rb initialiser:

config.parent_controller = "App::ApplicationController"

in your case if you move the application controller into an app/ subdirectory and namespace it. This tells devise which controller its controllers should inherit from and it defaults to ApplicationController which is why it can't find it when you've moved it.

like image 168
Tim Avatar answered Jan 31 '26 04:01

Tim


You should not move the application_controller.rb file from its original location, keep it on its original location. As far as naming class of the file app/controller/app/application_controller.rb it should be

class App::ApplicationController < ApplicationController
  ...
end

and other controllers under this directory inherits from App::ApplicationController class

like image 23
benchwarmer Avatar answered Jan 31 '26 02:01

benchwarmer