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