RESTful admin namespaced controller using scaffolding 7

Posted by Slobodan Kovačević on September 17, 2008

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|
    admin.resources :categories
    end
  • 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.

Share/Save/Bookmark

Trackbacks

Use this link to trackback from your own site.

Comments

Leave a response

  1. john Sun, 28 Dec 2008 04:44:12 UTC

    the following doesn’t work for me:

    script/generate controller admin/categories

    I’m doing script/generate controller user/accounts
    and I get the error:
    The name ‘user’ is either already used in your application or reserved by Ruby on Rails.
    Please choose an alternative and run this generator again.

    I would’ve expected this to generate an accounts_controller in the user namespace. I’m toying with the restful authentication framework, where this code has come from..

  2. Glenn Fri, 23 Jan 2009 00:09:22 UTC

    Now what about the functional tests? I was just messing with scaffolding today after being a long-time hand coding guy. It’s unfortunate you cannot just specify the namespace for the controller since this is such a common practice (especially for admin site as you noted).

  3. James Mon, 09 Feb 2009 02:59:51 UTC

    Awesome!

    Thank you

  4. James Thu, 12 Feb 2009 23:28:12 UTC

    I’ve been playing with this for a couple of days now and have found that it works perfectly for the scaffolded and model based routes.
    I am totally hooked on this solution but I am struggling with non model based routes.

    for example a generated admin/home controller on it’s own does not seem to like routes for link_to commands

    If I am trying to render a non model view with a link_to command I would normally use the :controller parameter. As this controller is now in an admin folder I’m faced with calling

    link_to(”Administration”, :controller => ‘admin/home’)
    Whilst this works it doesn’t ‘feel’ very restful and was wondering if you handle this scenario differently?

    Thanks

    James

  5. Slobodan Kovačević Fri, 13 Feb 2009 11:56:41 UTC

    I don’t think that there another way. That’s the only way to reference namespaced controller.

  6. Zoran Sat, 09 May 2009 10:38:37 UTC

    Good trick Slobo! Sadly there’s no other way.

  7. Andre Mon, 18 May 2009 04:29:34 UTC

    Thank you so much. Exactly the information I needed, not that pretty but now I can do what I want to achieve.

Comments