7

当首先加载全局应用程序控制器时,名称空间应用程序控制器在加载该名称空间内的页面时不加载。应用控制器看起来是这样的:Rails 3.2.3名称空间控制器被具有相同名称的全局控制器覆盖

class ApplicationController < ActionController::Base 
protect_from_forgery 
end 

而命名空间中的应用控制器看起来是这样的:“authenticate_admin”

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像这样:

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

“引用Admin :: AssetsController#new中的NoMethodError”。这只发生在命名空间路由之前我们点击全局路由时。如果服务器重新启动并且命名空间路由首先被加载,那么所有事情都可以正常工作。

+0

这些控制器在哪些文件? –

+0

app/controllers/admin/application_controller.rb, app/controllers/admin/assets_controller.rb和 app/controllers/application_controller.rb –

回答

9

这是发生,因为你也碰巧有一个Admin模型(一类)具有相同的名称作为您的命名空间中的新动作。

This Google组线程提供了一个很好的解释究竟发生了什么。

要解决这个问题,我要么将模型重命名为AdminUser,要么如果这不可能,重命名该命名空间也将解决该问题。

3

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

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 
+0

对不起,我之前没有提及它;控制器处于正确的目录结构中,完全按照您的说明命名。我们在AssetsController中执行了操作,因为它们看起来并不相关,所以我们没有将它们放在原始文章中。 –

相关问题