2

我的模型包含费用,包括用户和项目参考。

class Expense < ActiveRecord::Base
     attr_accessible :amount, :expense_date, :description, :project_id, :user_id

      belongs_to :project
      belongs_to :user
end

费用控制器处理费用的基本 CRUD 操作。

我现在需要构建同一页面的管理员版本,最好是一个新视图,它可以包括数据的不同视图,按用户,按项目等,还可以编辑用户无法编辑的数据。

我的问题是:构建第二个控制器来处理数据的管理视角,或者我是否在每个方法内部设置条件,以检测原始视图和表单,然后条件将它们重定向回它们所属的位置?

如果我确实构建了第二个控制器,我如何正确设置 form_for 以便它知道要转到哪个控制器?

谢谢!

PS - 如果有人有任何关于如何正确组合 Rails 应用程序的书籍,我觉得我知道这些部分,但我被困在大图实施上。我在 Michael Hartl 的指南中学习了 Rails,在此之前我是一名 PHP 开发人员。

4

3 回答 3

3

恕我直言,如果安全性是您的应用程序的一个大问题,那么使用管理命名空间和单独的控制器是确保您不会留下任何空白的最佳方法。它也更简单,压力更低。

我会有一个像这样的目录结构:

/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).

于 2012-11-25T23:07:06.193 回答
2

如果您想添加另一个控制器,我建议在模块中使用通用代码并将它们导入每个控制器中。每个控制器也将有一个足够的前置过滤器来检查是否有足够的权限。

但我更喜欢拥有一个控制器和一组视图,因为我认为它可以避免代码重复和/或混淆。当您需要决定 form_for 的 URL 或是否隐藏或显示某些部分时,将用户作为局部变量传递给视图并检查管理员权限。

如果视图差异很大,请检查控制器中的管理员权限并呈现用户视图或管理员视图。

您甚至可以为视图的管理部分创建一个特殊的部分,并决定是否在视图中呈现它,是否在参数中发送适当的数据。

于 2012-11-25T22:20:59.070 回答
1

您可以使用 Devise gem 进行身份验证。您可以为应用程序的管理部分创建某种“命名空间”。

我认为,创建另一个控制器取决于您的管理员将访问多少视图和操作。

关于 form_for 操作的疑问,它将由您在 form_for 参数中配置的路由和路径管理。

于 2012-11-25T22:31:38.673 回答