Take the 2-minute tour ×

Once my Rails 3 app is loaded, a user can click an item which needs to then load a dynamic subnav.

My thinking is (since it needs to be dynamic) is onClick to make a jQuery AJAX call to the server and then to inject the HTML response into a DIV on the page...

What I'd like your advice on is how/where the subnav logic should live in the rails app, as I don't have a navigation controller or view... But maybe I should have one?

Do I create a navigation controller? Or use the application controller? I also have a pages controller that I use for the landing page, about, contact, etc...


share|improve this question

1 Answer 1

up vote 1 down vote accepted

For me, I would use a navigation controller rather than the application controller as the application controller growths extremely complex easily.

This should create a view folder in app/views/navigation. I would also put all my navigation templates here (including you main nav).

So there might be those files:

  _main_nav.html.erb # made it a partial file for including in other pages
  subnav.html.erb # or subnav.js.erb if you don ajax call and return scripts

and in your layout files, where you want the main nav, you just render it.

So even tomorrow you suddenly want two or three different navigation menus, and there ajax calls, you have a centralized place to handle them, instead of putting them all inside the application controller.

Another more suggestion is, generate the navigation controller under some scopes. Like app/controllers/page_structures/navigation_controller.rb, so your views will be in app/views/page_structures/navigation/

In this way, you could put all your page structure related things like sidebars, custom headers, banners, etc inside the same scope page_structures.

===== UPDATE =====

Since your AJAX calls seems relatively static, I would suggest your paths use some kind of direct match.

If my guess correct, your top navigation have some items, and each item has their own sub-menu. So you will want to load the sub-menu one by one but not all. (If actually it's all, then you could just include them all in rendering...)

/page_structures/:top_nav/:sub_nav_template_name # So in here I assumed you will have many navigations and sub-nav to load.

then we match this path to the following action:

def get_sub_nav
  # checks both params[:top_nav] and params[:sub_nav_template_name] exist and not pointing to some other dangerous place. (I don't know if this work if the input is './' or '../' these kind of things
  render "page_structures/navigation/#{params[:top_nav]}/#{params[:sub_nav_template_name]}"

By this simple action, whenever you added more navigation / navigation items, you just need to create the corresponding AJAX response template. in this way, you are doing the minimal things!

Of course, if some how you have some items will need to return some other data as the response, such as responding sub-categories, you may need to create other routes to let you pass your parent category id.

You could think like that: my suggestion is for the default relatively static centralized sub-nav But if you need some specialized sub-nav, which need other data to process, for each one you will have to create a route and an action in the navigation controller to accept your category id, product id, etc. But still, these template file could following the same filing way.

share|improve this answer
Very cool, I'm going to try that now... What do you suggest for the route, since I'm making an AJAX call to get the subnav? /page_structures/nav/subnav/ ? –  AnApprentice Sep 26 '10 at 3:09
Since those AJAX call paths are usually for internal use, not open for public (and most likely post request), I at least don't mind how's they appear. Using ugly & difficult to guess path could increase slightly security issue... –  PeterWong Sep 26 '10 at 14:57
For simplicity (as your calls looks like just getting the template, not saving or destroying anything), so I would suggest some direct-map to minimize effort. Please see my update...... –  PeterWong Sep 26 '10 at 14:59

Your Answer


