Issue with variables in a partial view

I had a partial to display a list of ‘stories’, done in the traditional
rails-tutorial kind of way - eg, an ‘article’ has a list of ‘stories’,
so i have a partial called ‘story_list’ that has this:

for story in @article.stories
blah blah - some html and erb that works with ‘story’
end

and i call it from the article’s show page with

Story list

<%= render :partial => ‘story/story_list’ %>

so far so standard, right? That all works fine.

However, in another place in my app i want to display a different set of
stories (ones just done by the current user). To stay nice and DRY, i
want to use just one partial to display the stories, whichever bunch of
stories makes up the collection. So, i moved the start and end of the
for loop out of the partial: now, the view page that calls the partial
decides what makes up the collection, and the partial shows a single
item. So now i have, in the calling view,

Story list

for story in @article.stories
<%= render :partial => ‘story/story_list’ %>
end

and the partial is now simply

blah blah - some html and erb that works with ‘story’

The problem is this: now, the partial doesn’t know what ‘story’ is - ie
the local variable ‘story’ isn’t being passed through to the partial.
But i thought that the partial was effectively pasted into the calling
view page before being processed? In which case it shouldn’t matter?

I can get around this by passing through ‘@story’ instead of ‘story’,
but i’d like to understand the problem rather than work around it. Can
anyone explain? Is a partial call effectively a method call, so local
vars won’t work, or something?

sorry for the long winded post…
max

hi Max,

you can pass make a local variable available to partial by send it as
part of :locals, like this

for story in @articles.stories
<%= render :partial => “story/story_list”, :locals => { :story =>
story } %>
end

On Sep 4, 2:15 pm, Max W. [email protected]

raghukumar wrote:

hi Max,

you can pass make a local variable available to partial by send it as
part of :locals, like this

for story in @articles.stories
<%= render :partial => “story/story_list”, :locals => { :story =>
story } %>
end

On Sep 4, 2:15 pm, Max W. [email protected]

Good tip, thanks!

Max W. wrote:

I had a partial to display a list of ‘stories’, done in the traditional
rails-tutorial kind of way - eg, an ‘article’ has a list of ‘stories’,
so i have a partial called ‘story_list’ that has this:

for story in @article.stories
blah blah - some html and erb that works with ‘story’
end

and i call it from the article’s show page with

Story list

<%= render :partial => ‘story/story_list’ %>

so far so standard, right? That all works fine.

However, in another place in my app i want to display a different set of
stories (ones just done by the current user). To stay nice and DRY, i
want to use just one partial to display the stories, whichever bunch of
stories makes up the collection. So, i moved the start and end of the
for loop out of the partial: now, the view page that calls the partial
decides what makes up the collection, and the partial shows a single
item. So now i have, in the calling view,

Story list

for story in @article.stories
<%= render :partial => ‘story/story_list’ %>
end

and the partial is now simply

blah blah - some html and erb that works with ‘story’

The problem is this: now, the partial doesn’t know what ‘story’ is - ie
the local variable ‘story’ isn’t being passed through to the partial.
But i thought that the partial was effectively pasted into the calling
view page before being processed? In which case it shouldn’t matter?

I can get around this by passing through ‘@story’ instead of ‘story’,
but i’d like to understand the problem rather than work around it. Can
anyone explain? Is a partial call effectively a method call, so local
vars won’t work, or something?

As this is a common pattern, Rails already has a built-in to do it
easily. Once you have the partial for rendering an item in the story
list, you can use it like so:

Story list

<%= render :partial => ‘story/story_list’, :collection =>
@article.stories %>

Take a look at the docs for render :partial.


Josh S.
http://blog.hasmanythrough.com

Josh S. wrote:

As this is a common pattern, Rails already has a built-in to do it
easily. Once you have the partial for rendering an item in the story
list, you can use it like so:

Story list

<%= render :partial => ‘story/story_list’, :collection =>
@article.stories %>

Take a look at the docs for render :partial.


Josh S.
http://blog.hasmanythrough.com

ahh…that’s perfect, thanks. Looking at my copy of ‘agile web dev with
ror’, i see it all explained nicely. Should have looked there first (as
usual). :slight_smile:

In case anyone else is looking at the above and thinking “but what are
the individual items from the collection (that we’d normally call
‘story’) called once we get into the partial?”, the answer is that it
has the same name as the partial: so ideally i’d rename the partial to
be called ‘_story.rhtml’, and then i can just carry on using

blah blah - some html and erb that works with ‘story’

inside the partial.

thanks josh!