问题
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.
回答1:
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.
回答2:
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
来源:https://stackoverflow.com/questions/10902023/rails-3-2-3-namespaced-controllers-being-overridden-by-global-controllers-with-s