15

I've seen a couple questions on this but haven't been able to solve it...

I'm trying to pass a parameter while rendering a partial (similar to domainname.com/memory_books/new?fbookupload=yes)

Right now, I use this line:

<%= render :partial => '/memory_books/new', :fbookupload => "yes" %>

and in the partial, I have tried to get the content of fbookupload by using:

<%= fbookupload %>

which gives an "undefined local variable" error and

<%= params.inspect %>

which does not show fbookupload as a parameter.

How can I have the partial pass along the parameter :fbookupload?

Thank you.

UPDATE:

Could it have anything to do with the fact that I'm rendering this within a render?

i.e. the page (/fbookphotos/show) that has

<%= render :partial => '/memory_books/new', :fbookupload => "yes" %>

is being rendered by another page with (posts/show) via:

<%= render :partial => '/fbookphotos/show' %>

so I'm rendering this within a render.

Mike Morgan
  • 93
  • 2
  • 9
user749798
  • 5,210
  • 10
  • 51
  • 85

5 Answers5

20

try this:

<%= render :partial => '/memory_books/new', :locals => {:fbookupload => "yes"} %>
Someth Victory
  • 4,492
  • 2
  • 23
  • 27
18

Taking it out of the comments for posterity. This syntax is correct:

render '/memory_books/new', fbookupload: "yes"

But if there is a reference to rendering the same partial without specifying the local variables, e.g.

render '/memory_books/new'

then fbookupload variable becomes unavailable. The same applies to multiple local variables, e.g.

render 'my_partial', var1: 'qq', var2: 'qqq'

will work if only occurs once. But if there is something like that somewhere else in the code

render 'my_partial', var1: 'qq'

then the var2 will become unavailable. Go figure ...

Vadym Tyemirov
  • 8,288
  • 4
  • 42
  • 38
1

To do it your way:

In the main view:

<% fbookupload = "yes" %>
<%= render :partial => '/memory_books/new', :locals => {:fbookupload => fbookupload} %>

And in the partial:

<%= fbookupload %>

2nd option:

Ideally in the controller, otherwise in the view, define an instance variable: @fbookupload = "yes". Then it is available everywhere. The partial will then be : <%= @fbookupload %>

Anil
  • 3,899
  • 1
  • 20
  • 28
1

Params is just request parameter, so if u want to pass it in params u have to add it to your url ?fbookupload=yes or assign it params[:fbookupload] = "yes", but i don't think that is a good idea.

But if u need to use params[:fbookupload]', u can replace it withparams[:fbookupload] || fbookupload', and pass fbookupload in locals hash for partial.

Yuri Barbashov
  • 5,407
  • 1
  • 24
  • 20
  • how would i add it to the url in a render? when i do <%= render :partial => '/memory_books/new?fbookupload=yes' %>, I get a "Missing partial" error – user749798 Jul 01 '12 at 16:53
  • not in a partial, but in your browser url...but is not a good way to do, don't use params in partials, use local vars – Yuri Barbashov Jul 01 '12 at 17:01
  • @Yuri Barbashov: You are confusing two things: URL parameters given to a view, and parameters given to a partial. Depending on the value of incoming URL parameters, different views and/or partials might be displayed, but that is determined after a controller parses the URL parameters. I suppose that one **could** use incoming URL parameters to conditionally redirect to a different view, and possibly use URL parameters in this redirect (actually, I don't even know if the latter is possible), but that's not really what the redirect is for, and strikes me as Not A Good Thing. – Teemu Leisti Jun 25 '13 at 12:11
  • @TeemuLeisti I am not confusing two things: `params` in partials contains url parameters. If you look at the question you will see that he tried to inspect `params', so i showed how he can achieve that by assigning params value and told that this is not а good thing. – Yuri Barbashov Jun 26 '13 at 09:41
  • @Yuri Barbashov: Right, user749798 said "similar to" an URL with parameters. However, the **direct** reason for rendering a **partial** view is because **another view** is asking that. For this case, Rails has a standard method for parameters passing (see the answers by Someth Victory and Anil). Trying to achieve the same with using URL parameters seems to me to be an ugly hack, if it is even possible. URL parameters are the standard parameter passing mechanism for controller methods, which then render **normal** views. But if you disagree, then we'll just have to agree to disagree. – Teemu Leisti Jun 26 '13 at 13:02
  • @Yuri Barbashov: but OK, you said you thought it wasn't a good thing, which I missed at first. I tried to undo my negative vote on your answer, but it's not possible unless the answer is edited. – Teemu Leisti Jun 26 '13 at 13:05
1

render can be called with or without the partial param, and there seems to be some confusion around the differences between these two forms.

The following two are equivalent:

<%= render "my_partial', my_param: true %>

and:

<%= render partial: "my_partial', locals: { my_param: true } %>

The first is a shorthand that allows you to omit partial:. With this shorthand, local variables are also not nested under locals:. This is explained well in the documentation (see 'Rendering the default case').

In the two cases above, you would access my_param in the partial directly with my_param.

One other source of confusion is that if you render the partial somewhere without passing my_param, then the partial will fail when it tries to access it. To get around this, you can access the local with local_assigns[:my_param] instead of my_param, which will give you nil if the param is not defined instead of erroring, as described in this documentation. Another alternative is to use defined?(my_param) before accessing it.

stephen.hanson
  • 9,014
  • 2
  • 47
  • 53