Take the 2-minute tour ×

In my Rails app, I have the following method:

def navigation_menu(items)
  # raise items.class.to_s
  # raise items.to_yaml
  render partial: 'global/navigation_menu', locals: items

If I uncomment the first line of the method, "Hash" is shown for the exception text, proving that items is a hash. If I uncomment the second line, the members of the hash are shown, so I also know it's not empty.

That method fails with the following error:

comparison of String with :navigation_menu failed

If I replace locals: items with locals: { dummy_key: 'dummy value' }, it works.

Why can't I use my items variable in place of an explicit hash?

share|improve this question
add comment

4 Answers

up vote 1 down vote accepted

What you wrote should work, I often proceed this way.

There is a particular case though: Hashes having keys as strings fail to be interpreted correctly. So it's necessary in this case to append symbolize_keys to the Hash:

  render partial: 'global/navigation_menu', locals: items.symbolize_keys
share|improve this answer
add comment

Just a Ruby/Rails newb here, but I had the same problem, :locals is a options hash, so whatever you pass to :locals would be a hash of options... what I mean is for e.g.

you need to code this way, and if you read eloquent ruby, it states why - unless the parameter is the last hash you can omit the braces...

render partial: 'global/navigation_menu', :locals => { :items => item } 

or if you prefer

render partial: 'gloabl/navigation_menu', locals: { items: items }

the braces have to be there in the either syntax, although I haven't tried NOT using the braces in the first e.g. in the second however, I believe those are required.

hope this helps!

share|improve this answer
That's my workaround at the moment. However, I don't want that intermediary items variable. :( Basically, I'm trying to avoid having to do local_assigns[:items]. I suppose I don't understand why I can't pass a hash directly to it rather than having to create one on the spot. +1 regardless. –  ClosureCowboy Aug 3 '11 at 7:12
add comment

I guess you need to include the arrow '=>' and put it in a hash {} like this:

render :partial => "global/navigation_menu", :locals => { :items => items }
share|improve this answer
add comment

The reason you are unable to simply pass locals as the second parameter is that you are specifying a hash of options to render() - in this case your hash contains :partial. If you take a look at the documentation and code for render, you'll see that the method is defined as:


Now, if you want to shorten the call to render a partial a bit, there is a shortcut when rendering a partial with no options: "If no options hash is passed or :update specified, the default is to render a partial and use the second parameter as the locals hash." You can do the following:

render 'global/navigation_menu', items

Check out 'Rendering the default case' in the partials documentation for more info.

share|improve this answer
add comment

Your Answer


