Most of my clients prefer to have a separate admin section. In turn, I like to have separate controllers for admin section and front-end in my Rails app. This is not as straightforward as it might seem, especially if you like to use scaffolding for admin controller.
The goal is to get 2 separate RESTful controllers, admin & front-end controller, one model and for admin pages to have scaffolding.
Here is the easiest way I found so far to accomplish this. This example generates categories model and controllers for it.
./script/generate controller admin/categories
./script/generate scaffold category name:string
This will generate an empty controller in admin namespace and a scaffolded resource for front-end controller.
Now we have everything generated we just need to make it work with admin controller and not with front-end.
- move all templates from app/views/categories to app/views/admin/categories
- copy all functions from categories_controller.rb to admin/categories_controller.rb
- add namespace for admin controller in routes.rb:
map.namespace :admin do |admin|
- in admin/categories_controller.rb replace in 3 places redirect_to calls to work with admin namespace. It will have something like redirect_to(@category), but to work with namespace it needs to have redirect_to([:admin, @category])
- make similar changes in all templates, i.e. make it work within an admin namespace. You need to make following changes:
- form_for(@category) => form_for([:admin, @category])
- <%= link_to ‘Show’, @category %> => <%= link_to ‘Show’, [:admin, @category] %>
- categories_path => admin_categories_path
- edit_category_path(@category) => edit_admin_category_path(@category)
- new_category_path => new_admin_category_path
That’s it. Now you’ll have /admin/categories for all administrative tasks and you have a free controller for front-end actions.
You might wonder why not just generate scaffold for admin/categories… The reason is that you’ll also get a model that is namespaced in admin (i.e. model would be Admin::Category). Scaffolded views also wouldn’t work as it seems that generator doesn’t take into account the fact that you are using a namespace.