How to organize controller in moderately large Rails application?

爷,独闯天下 提交于 2019-12-04 09:55:56

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!

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!