8

This code is working fine:

<%= render 'sidebars/pages', :object => @categories = pages , :object => { @myobject => '1', @mmyobject => '2' } %>

If I change to this:

<%= render 'sidebars/pages', :object => { @categories => pages, @myobject => '1', @mmyobject => '2' } %>

Then I receive a error from the partial when it try to iterate @categories:

undefined method `each' for nil:NilClass

I'm very new to ruby and rails also, I appreciate any help.

Cheers!

2 Answers 2

15

When you pass an :object to a Rails partial, a local variable (not an instance variable, beginning with @) is defined within the partial which has the same name as the partial. So for the partial sidebars/_pages.html.erb, your local variable will be called pages.

The value of the pages local variable is the Hash you passed as the value of the :object option, and none of the instance variables you had in your "outer" view will be available (such as @categories or @myobject). So you'll need to access those via the pages local variable.

You're probably looking for something like this:

<%= render 'sidebars/pages', :object => { :categories => @categories, :myobject => '1', :mmyobject => '2' } %>

And in sidebars/_pages.html.erb, you might have something like this:

<p><%= pages[:myobject] %></p>

<ul>
<% pages[:categories].each do |category| %>
  <li><%= category %></li>
<% end %>
</ul>

See the Rails Guide to Layouts and Rendering's Partials section for more details.

Update:

An even better solution would be to use the :locals option, which accepts a Hash whose keys become local variables with the partial. For instance:

<%= render 'sidebars/pages', :locals => { :categories => @categories, :myobject => '1', :mmyobject => '2' } %>

And in sidebars/_pages.html.erb, you might have something like this:

<p><%= myobject %></p>
<p><%= mmyobject %></p>

<ul>
<% categories.each do |category| %>
  <li><%= category %></li>
<% end %>
</ul>
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for the quick reply Mr. Stuart, pages is a method from a helper, it only returns Category.all. I am using @categories.each do |c| inside the partials. I'm aware about the best practice of using local variables instead of instance variables, I was just curious why my second line of code doesn't work.
I'm not certain, but your second line of code may not be working because your Hash is setting @categories => pages. You probably don't want to have the Hash key be @categories, since you won't be accessing it via that key. It should probably be something like :categories => pages.
Mr. Stuart, I double-checked my first line of code and I noticed the @myobject and @mmyobject are not being passed to the view, since it does not raise any errors I was led to believe it was fine. I apologize for missing this.
1

This line of code as mentioned above:

<%= render 'sidebars/pages', :object => @categories = pages , :object => { @myobject => '1', @mmyobject => '2' } %

Actually does not raise any errors but also does not pass @myobject and @mmyobject to the view.

Below is the correct* approach for specifying multiple objects with the render method:

<%= render 'sidebars/pages', :object => [@categories = pages, @myobject = '2'] %>

Like this I can pass multiple objects to the view, without having to define :object more than once.

*at least for my knowledge scope

4 Comments

I think you may be misunderstanding what @categories = pages is doing: that is setting the instance variable @categories to pages. Doing that assignment in the render statement isn't syntactically invalid, but it doesn't really give you anything. For instance, it does not mean you can access @categories within the partial.
I think you may be best off using the :locals option instead of :object. You could say render 'sidebars/pages', :locals => {:categories => @categories, :myobject => '2'}, and then you would have access to local variables called categories and myobject within the partial. See the "Passing Local Variables" section of the Rails Guide.
Yes, I understand sir. I was just trying to figure out how to have instance variables available to a partial coming from a view, since <%= render 'sidebars/pages' %> lives inside a view and so far I knew only to pass multiple locals or one object at once from a view to a partial. With my example above I have available @categories in the partial, I double-checked this time. The method pages comes from a helper for testing purposes and is the same as Category.all. I'm testing with Rails 4.
I'm using @categories = pages because I dont want it to be in the controller, if I make it available in the ApplicationController using the before_filter, then it will be requested even when it is not in use.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.