Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing @object into a rails partial render

I have a partial:

'profiles/_show.html.erb'

that contains code like

<%= @profile.fullname %>

I'm trying to render the partial but I'm not sure how to pass the @profile. I tried using local but apparently it sets 'profile' on my partial instead of '@profile'.

<%= render :partial => 'profiles/show', :locals => {:profile => @app.profile} %>

Is there anyway to pass it as @object instead of object, or is it designed this way?

like image 789
David C Avatar asked Dec 05 '09 02:12

David C


4 Answers

Why is it so important that you use an instance variable(variables who's names begin with '@', eg: @object) in your partial? It's not a good habit to get into. Using instance variables in partials complicates the control flow, which facilitates bugs and makes reuse of partials more difficult. This blog post explains the problem a little more in depth.

Really you have two options. The first option is the suggested solution.

  1. Change all instance variables to a local variable and pass it to the partial with the locals argument of render.

  2. Set the instance variable before the partial is rendered. Partials have access to all the instance variables that your controller sets.

Again instance variables in partials are bad. You should never set instance variables just because your partials are already written to use them. Rewrite the partial instead.

like image 198
EmFi Avatar answered Oct 19 '22 11:10

EmFi


Indeed, quoting this blog post you should know:

A partial is a reusable view template, it allow you to modularize the components which make up a particular page into logical, cohesive pieces. When required data is not passed into a partial, it is often difficult to reuse or change later.

The rails guides site explains some simple use cases:

You can also pass local variables into partials, making them even more powerful and flexible. For example, you can use this technique to reduce duplication between new and edit pages, while still keeping a bit of distinct content ...

So in your specific case there is a simple and powerful way to do that

<%= render partial: 'show', locals: {profile: @profile} %>

Extra tip:
Probably a partial named show is not a good option, give it a more meaningful name related to the thing you are trying to reuse. This sounds even more error/confusion prone in a RESTful scenario when you actually have a show method, so probably would be a _show.html.erb file and a show.html.erb file.

Hope this helped.

like image 45
Javier Cadiz Avatar answered Oct 19 '22 13:10

Javier Cadiz


For Rails 3+, the answer to your actual question is:

<%= render 'profiles/show', :@profile => blah %>

Your partial will now see @profile locally.

I'm not saying this is a good approach. I'm honestly not sure if this is ugly or not. But it works.

like image 6
Grant Birchmeier Avatar answered Oct 19 '22 11:10

Grant Birchmeier


You could always do @profile = profile in the partial.

like image 1
Jim Avatar answered Oct 19 '22 12:10

Jim