Rails 3.2.3命名空间控制器被具有相同名称的全局控制器覆盖

首先加载全局应用程序控制器时,在该名称空间中加载页面时,不会加载命名空间的应用程序控制器。 应用程序控制器如下所示:

class ApplicationController < ActionController::Base protect_from_forgery end 

命名空间的应用程序控制器如下所示:

 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 

当我们使用before_filter“authenticate_admin!”时 像这样:

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

抛出“Admin :: AssetsController #new中的NoMethodError”。 仅当我们在命名空间路由之前命中全局路由时才会发生这种情况。 如果服务器重新启动并且加载了命名空间路由,则一切正常。

发生这种情况的原因是您碰巧有一个与您的命名空间同名的Admin模型(一个Class)。

这个 Google群组线程可以很好地解释究竟发生了什么。

要修复,我会将模型重命名为AdminUser或者如果不可能,重命名命名空间也将解决问题。

命名空间控制器需要出现在正确的目录结构中。

app/controllers/admin/application_controller.rb

app/controllers/admin/assets_controller.rb

就个人而言,我建议不要为命名空间的基本控制器重载ApplicationController名称。 这不会导致问题,但这是一个优先事项 – 只有一个应用程序,应该只有一个ApplicationController 。 如果这是Admin命名空间的目的,您可以使用ContentManagementController

其次,最好使用module关键字并以这种方式定义控制器:

 module Admin class ContentManagementController < ApplicationController # .. end end # app/controllers/admin/content_management_controller.rb 

编辑:我也刚刚看到了具体的错误(也许您的问题已更新?) - 您需要在AssetsController上定义新操作

 def new # end