如何在中等规模的 Rails 应用程序中组织控制器?

发布于 2024-09-09 00:45:03 字数 554 浏览 12 评论 0原文

我正在开发一个具有相当多相关模型的应用程序,并且想听听一些关于如何最好地组织控制器的意见。

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

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

2) 创建嵌套资源。我只是偶尔使用嵌套资源,因此我并不总是清楚何时最好嵌套资源,而不是简单地通过参数显式传递所需的数据。有人对如何最好地使用嵌套资源有一些建议/示例吗?什么时候是个好主意?什么时候才算过分呢?

3) 只需保留默认的脚手架控制器即可。根据需要创建新的集合/成员操作,并在过滤器之前使用以设置每个控制器内的权限。这似乎最有吸引力,因为它让事情预先变得简单。但我有点担心事情会变得混乱,因为一些控制器可能会因为几个新动作而变得臃肿。

如果任何具有设计大型应用程序经验的人可以在这里提供一些指导,我们将不胜感激。

I'm working on an application with quite a few related models and would like to hear some opinions on how best to organize the controllers.

Here are some options I have been considering:

1) Namespace the controllers. So, for example, have a controllers/admin directory and a controllers/public directory. This seems appealing for organization but also sorta contrived since a single resource could often have actions which might sensibly belong in different directories (e.g. the show action is public whereas the create action is admin). So this would mean breaking up some of my resources into two separate controllers - one public, one admin. Seems bad.

2) Create nested resources. I've only occasionally used nested resources so it's not always clear to me when it's best to nest resources versus simply passing the data you need through the params explicitly. Does anyone has some suggestions/examples of how best to use nested resources? When is it a good idea? When is it an overkill?

3) Just leave the default scaffolded controllers alone. Create new collection/member actions where needed and use before filters to set permissions within each controller. This seems most appealing since it keeps things simple upfront. But I'm sorta nervous about things getting messy down the line as some of the controllers might start to bloat with several new actions.

If anyone with experience designing large applications could offer some guidance here, it'd greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

污味仙女 2024-09-16 00:45:03

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

首先,关于管理/用户功能的单独控制器,我会说您可能不想走那条路。我们使用授权和 before_filter 来管理应用程序内的权限。我们推出了自己的产品,但事后看来,我们应该使用 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

我们从中体验到的其他优点是易于设置菜单系统和选项卡。这些结构非常适合组织有序的场地。

我希望这有帮助!

For organizing within our applications, I have done a little bit of everything depending on the situation.

First, regarding the separate controllers for admin/user functions, I will say that you probably don't want to go that route. We used authorization and before_filter to manage rights within the application. We rolled our own, but 20/20 hind-sight, we should have use CanCan. From there you can setup something like this (this is pseudo-code, actual language would depend on how you implemented authorization):

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

Or at a higher level

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

and in your application controller

def require_admin
  redirect_to never_never_land_path unless current_user.administrator?
end

It would depend which route, but I would use that for authorization instead of splitting up controllers.

As far as name spaces vs. Nested Resources, it depends on the situation. In several of our apps, we have both. We use name spaces when there is a cause for a logical separation or there will be shared functions between a group of controllers. Case and point for us is we put administrative functions within a namespace, and within we have users, roles and other proprietary admin functions.

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

and then within those controllers we have a base controller, that stores our shared functions.

class Admin::Base < ApplicationController
  before_filter :require_admin
end

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

This provides us logical separation of data and the ability to dry up our code a bit by sharing things like the before_filter.

We use nested controllers if there is going to be a section of code where you want some things to persist between controllers. The case from our application is our customers. We search for and load a customer and then within that customer, they have orders, tickets, locations. Within that area we have the customer loaded while we look at the different tabs.

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

and that gives us urls:

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

Other advantages we have experienced from this is ease of setting up menu systems and tabs. These structures lend themselves well to an organized site.

I hope this helps!

前事休说 2024-09-16 00:45:03

另外,看起来嵌套资源超过一层的深度几乎肯定是一个坏主意:

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

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

如果有人不同意,我想听听为什么。

Also, looks like nesting resources more than one level deep is almost certainly a bad idea:

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

Yeah, it's a old article, but it makes a lot of sense to me.

If anyone disagrees, I'd like to hear why.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文