恕我直言,如果安全性是您的应用程序的一个大问题,那么使用管理命名空间和单独的控制器是确保您不会留下任何空白的最佳方法。它也更简单,压力更低。
我会有一个像这样的目录结构:
/app/controllers/application_controller.rb
/app/controllers/admin_controller.rb - inherits from application_controller
/app/controllers/expenses_controller.rb - non-admin, inherits from application_controller
/app/controllers/admin/expenses_controller.rb - inherits from admin_controller
您的视图将被类似地分开/重复:
/app/views/expenses/* - non-admin expenses views
/app/views/admin/expenses/* - admin expenses views
在 application_controller 中,您将 Devise 方法放入 authenticate_user 并将 CanCan 方法放入 check_authorization(如果在控制器操作中的某个时间点未检查授权,则会引发异常)。在 admin_controller 中,您有更严格的过滤器来确保用户是管理员。然后,您可以在特定控制器及其操作中获得更细粒度的信息。
当然,每个控制器只需要定义它真正需要的操作,您不必复制视图。也许非管理员的费用控制器有索引、显示、新建、创建,而管理员只有编辑、更新和销毁。然后在“显示”视图中,如果用户是管理员,您仍然会有添加指向“编辑”操作的链接的代码。
编辑 - 路线
在上面的例子中,你的 routes.rb 看起来像:
resources :expenses, :only => [:index, :show, :new, :create]
namespace :admin do
resources :expenses, :only => [:edit, :update, :destroy]
end
所以你仍然使用expenses_path()
索引和expense_path(foo)
显示。但是,管理页面上的表单将发布到admin_expense_path(@expense)
.