如何在适度大的Rails应用程序中组织控制器?

时间:2010-07-11 22:40:39

标签: ruby-on-rails model-view-controller controllers

我正在研究一个有很多相关模型的应用程序,并希望听到一些关于如何最好地组织控制器的意见。

以下是我一直在考虑的一些选项:

1)命名空间控制器。因此,例如,有一个控制器/管理目录和一个控制器/公共目录。这似乎对组织很有吸引力,但也因为单个资源通常可能具有明显属于不同目录的动作(例如,show动作是公共的而创建动作是admin)。所以这意味着将我的一些资源分解为两个独立的控制器 - 一个公共管理员,一个管理员。看起来很糟糕。

2)创建嵌套资源。我只是偶尔使用嵌套资源,所以我不总是清楚什么时候最好嵌套资源而不是简单地通过params传递你需要的数据。有没有人有一些关于如何最好地使用嵌套资源的建议/示例?什么时候这是个好主意?什么时候有点矫枉过正?

3)只保留默认的脚手架控制器。在需要时创建新的集合/成员操作,并在过滤器之前使用,以在每个控制器中设置权限这看起来最吸引人,因为它可以提前保持简单。但是,由于一些控制器可能会因为几个新动作而开始膨胀,我对于线路变得混乱感到紧张。

如果有任何有大型应用程序设计经验的人可以在这里提供一些指导,那就非常感激。

2 个答案:

答案 0 :(得分:5)

为了在我们的应用程序中进行组织,我根据具体情况做了一些事情。

首先,关于管理员/用户功能的单独控制器,我会说你可能不想走那条路。我们使用授权和before_filter来管理应用程序中的权限。我们推出了自己的,但20/20后视力,我们应该使用CanCan。从那里你可以设置这样的东西(这是伪代码,实际语言将取决于你如何实现授权):

before_filter :can_edit_user, :only => [:new, :create, :edit, :update] #or :except => [:index, :show]

protected

def can_edit_user
  redirect_to never_never_land_path unless current_user.has_rights?('edit_user')
end

或更高级别

before_filter :require_admin, :only [:new, :create]

并在您的应用程序控制器中

def require_admin
  redirect_to never_never_land_path unless current_user.administrator?
end

这将取决于哪条路线,但我会将其用于授权而不是拆分控制器。

就名称空间与嵌套资源而言,它取决于具体情况。在我们的几个应用程序中,我们都有。当存在逻辑分离的原因时,我们使用名称空间,或者在一组控制器之间将存在共享功能。我们的案例和观点是我们将管理功能放在命名空间中,并且我们拥有用户,角色和其他专有管理功能。

map.namespace :admin do |admin|
  admin.resources :users
  admin.resources :roles
end

然后在那些控制器中我们有一个基本控制器,它存储我们的共享功能。

class Admin::Base < ApplicationController
  before_filter :require_admin
end

class Admin::UsersController < Admin::Base
  def new
   ....
end

这为我们提供了逻辑上的数据分离,以及通过共享before_filter等内容来稍微干掉我们的代码的能力。

我们使用嵌套控制器,如果有一段代码需要在控制器之间保留一些东西。我们的应用案例是我们的客户。我们搜索并加载客户,然后在该客户中,他们有订单,票据,位置。在该区域内,我们在查看不同的标签时加载了客户。

map.resources :customers do |customer|
  customer.resources :tickets
  customer.resources :orders
  customer.resources :locations
end

这给了我们网址:

customers/:id
customers/:customer_id/orders/:id
customers/:customer_id/tickets/:id

我们从中获得的其他优势是易于设置菜单系统和标签。这些结构非常适合有组织的网站。

我希望这有帮助!

答案 1 :(得分:0)

此外,看起来像嵌套资源不止一个层次几乎肯定是一个坏主意:

http://weblog.jamisbuck.org/2007/2/5/nesting-resources

是的,这是一篇旧文章,但对我来说很有意义。

如果有人不同意,我想听听原因。