Adding a menu to the application layout

Hello all, I’ve been reading a lot of posts and most seem close to my
problem but I don’t see the real answer. Appreciate any help.

GOAL:
Populate the application.rhtml layout with a menu bar and also main
content. The menu bar content coming from MenuController class and main
content coming from other controller classes depending on what menu
option was selected.

CODE:
application.rhtml

<%= render “menu/menubar” %>

<%= yield :layout %>

menubar.rhtml
<% for mbar in @menubar %>
<%= link_to h(mbar.name), { :controller => h(mbar.controller),
:action => h(mbar.action)}, :class => ‘mainlevel’ -%>
<% end %>

WHAT WORKS:
No problem yielding the action methods from various controllers on the
application page when I enter the url manually.

WHAT DOESN’T WORK:
Can’t get the menu to show up, I get ‘You have a nil object when you
didn’t expect it!’ because @menubar does not get populated.

SOLUTION:
I believe I’m taking the right approach but know that I need
@menubar = Menu.find(:all)
to be in a controller but which one as there are three that use the
application.rhtml to populate it with content.

Hope this makes sense, please let me know if you have any ideas.
Thanks…Bill

Your approach is not going to work because of MenuController. For what
I know, you usually have only one controller acting per request. If
you need to switch to another controller, you usually do that trough a
redirect_to.

What you want is a Menu model. There you add all your business logic
and create a method like menus_for(controller). Then on that partial
you can use Menu.menu_for(request[:controller]) instead of @menubar.

Then if you want to create an interface to manipulate your menus, add
items, reorder and etc you create MenuController.

You want to have all the data and business logic in the Menu MODEL.
The MenuController would be used to manipulate the data in that model,
ie add a new menu item.

That’s my point of view, how I would do it…

On Dec 26, 3:02 pm, Bill M. [email protected]

On Dec 26, 2007, at 5:02 PM, Bill M. wrote:

Hope this makes sense, please let me know if you have any ideas.
Thanks…Bill

Hi Bill,

If this needs to be loaded for every controller, which it sounds like
it does, you could put a before filter in application.rb (the
ancestor to all controllers). It would look something like

class ApplicationController < ActionController::Base
before_filter :load_menu

def load_menu
@menu = …
end
end

Since you define the before filter in application.rb, it
automatically runs at the beginning of all other controllers. If you
want to control which controllers call it, take out the before_filter
line in application.rb and put it in each controller you want to call
the method.

Hope that makes sense.

Peace,
Phillip

Phillip K. wrote:

On Dec 26, 2007, at 5:02 PM, Bill M. wrote:

Hope this makes sense, please let me know if you have any ideas.
Thanks…Bill

Hi Bill,

If this needs to be loaded for every controller, which it sounds like
it does, you could put a before filter in application.rb (the
ancestor to all controllers). It would look something like

class ApplicationController < ActionController::Base
before_filter :load_menu

def load_menu
@menu = …
end
end

Since you define the before filter in application.rb, it
automatically runs at the beginning of all other controllers. If you
want to control which controllers call it, take out the before_filter
line in application.rb and put it in each controller you want to call
the method.

Hope that makes sense.

Peace,
Phillip

Thanks guys for your quick response!
Phillip…I ended up taking your suggestion and it worked like a charm,
just what I wanted to do.
I really appreciate the help…Bill

Use the yield call with content for helper method

Sent from my iPhone

On Dec 26, 2007, at 3:02 PM, Bill M.
<[email protected]