我正在研究一个有很多相关模型的应用程序,并希望听到一些关于如何最好地组织控制器的意见。
以下是我一直在考虑的一些选项:
1)命名空间控制器。因此,例如,有一个控制器/管理目录和一个控制器/公共目录。这似乎对组织很有吸引力,但也因为单个资源通常可能具有明显属于不同目录的动作(例如,show动作是公共的而创建动作是admin)。所以这意味着将我的一些资源分解为两个独立的控制器 - 一个公共管理员,一个管理员。看起来很糟糕。
2)创建嵌套资源。我只是偶尔使用嵌套资源,所以我不总是清楚什么时候最好嵌套资源而不是简单地通过params传递你需要的数据。有没有人有一些关于如何最好地使用嵌套资源的建议/示例?什么时候这是个好主意?什么时候有点矫枉过正?
3)只保留默认的脚手架控制器。在需要时创建新的集合/成员操作,并在过滤器之前使用,以在每个控制器中设置权限这看起来最吸引人,因为它可以提前保持简单。但是,由于一些控制器可能会因为几个新动作而开始膨胀,我对于线路变得混乱感到紧张。
如果有任何有大型应用程序设计经验的人可以在这里提供一些指导,那就非常感激。
答案 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
是的,这是一篇旧文章,但对我来说很有意义。
如果有人不同意,我想听听原因。