Rails 3.2.3 namespaced controllers being overridden by global controllers with same name
Asked Answered
G

2

7

When the global application controller is loaded first, the namespaced application controller does not load when loading pages within that namespace. The application controller looks like this:

class ApplicationController < ActionController::Base
 protect_from_forgery
end

And the namespaced application controller looks like this:

class Admin::ApplicationController < ApplicationController

def authenticate_admin!
 if current_admin.nil?
  redirect_to new_admin_session_url
 end
end

private

 def current_admin
  @current_admin ||= Admin.find(session[:admin_id]) if session[:admin_id]
 end

helper_method :current_admin
end

When we use the before_filter "authenticate_admin!" like this:

class Admin::AssetsController < Admin::ApplicationController
  before_filter :authenticate_admin!
end

A "NoMethodError in Admin::AssetsController#new" is thrown. This only occurs when we hit the global route before the namespaced route. If the server is restarted and the namespaced route is loaded first everything works properly.

Guthrun answered 5/6, 2012 at 17:31 Comment(2)
What files are these controllers in?Pourparler
app/controllers/admin/application_controller.rb, app/controllers/admin/assets_controller.rb and app/controllers/application_controller.rbGuthrun
D
9

This is happening because you also happen to have an Admin model (a Class) with the same name as your namespace.

This Google group thread provides a good explanation of what exactly is happening.

To fix, I would either rename the model to AdminUser or if that is not a possibility, renaming the namespace will also fix the issue.

Daubigny answered 5/6, 2012 at 18:41 Comment(0)
P
3

Namespaced controllers need to appear within the correct directory structure.

app/controllers/admin/application_controller.rb

app/controllers/admin/assets_controller.rb

Personally, I would advise against overloading the ApplicationController name for a namespaced base controller. This would not be causing the problem but it is a matter of preference - there is only one application, and there should only be one ApplicationController. You might use ContentManagementController if that is the purpose of the Admin namespace.

Second, it's better practice to use the module keyword and define your controllers in this way:

module Admin
  class ContentManagementController < ApplicationController
      # ..
  end
end

# app/controllers/admin/content_management_controller.rb

edit: I also just saw the specific error (maybe your question was updated?) - you need to define the new action on the AssetsController

def new
   #
end
Polley answered 5/6, 2012 at 17:55 Comment(1)
Sorry I didn't mention it before; the controllers are in the correct directory structure, named exactly as you stated. We have actions in the AssetsController, we just didn't put them in the original post as it did not seem relevant.Guthrun

© 2022 - 2024 — McMap. All rights reserved.