Right now I have something like this:
<%= render :partial => "widgets/type1.html.erb", :locals => {:widget => #wall} %>
I have 50 different types
widgets/type1.html.erb
widgets/type2.html.erb
widgets/type3.html.erb
widgets/type4.html.erb
....
In the widget object, there is a widget.type which has the type2 etc... Is there a way I can make the partial dynamic to avoid all the if statements?
Thanks
Since you can tell rails to render :partial=>string, you can do string replacement inside that string. So, if #widget is the variable name:
<%= render :partial => "widgets/#{#widget.type}", :locals => {:widget => #wall} %>
Related
Here is the API definition for render:
render(options = {}, locals = {}, &block)
Returns the result of a render that’s dictated by the options hash. The primary options are:
:partial - See ActionView::Partials.
:file - Renders an explicit template file (this used to be the old default), add :locals to pass in those.
:inline - Renders an inline template similar to how it’s done in the controller.
:text - Renders the text passed in out.
There is no explanation about what's the purpose of locals here? What's locals for?
Thanks.
To pass local variables to the partial template, as opposed to controller instance variables.
See Section 3.4.4, Passing Local Variables in the Layouts and Rendering Guide.
For example:
<%= render :partial => "account" %>
This means there is already an instance variable called #account for the partial and you pass it to the partial.
<%= render :partial => "account", :locals => { :account => #buyer } %>
This means you pass a local instance variable called #buyer to the account partial and the variable in the account partial is called #account. I.e., the hash { :account => #buyer } for :locals is just used for passing the local variable to the partial. You can also use the keyword as in the same way:
<%= render :partial => "contract", :as => :agreement
which is the same as:
<%= render :partial => "contract", :locals => { :agreement => #contract }
How can I pass a is_featured = true to the following partial?
<%= render :partial => 'stores', :collection => #stores %>
I only need to pass the is_featured in one place (in all other places I call the partial as above.
You can use the locals option of render
<%= render :partial => 'stores', :collection => #stores, :locals => { :is_featured => is_featured } %>
In the partial you would access it as a method:
<%= is_featured %>
In my new.html.erb page, i use the following line to render a partial and it works fine.
<%= render :partial => "submissions/player_form", :locals => { :submission => #submission } %>
Now i want to render exactly the same partial via RJS
<p>Player Type: <%= f.select(:PLAYER_TYPE, $playersList, {:prompt => 'Select the Player Type'} %></p>
<%= observe_field("submission_PLAYER_TYPE", :frequency => 1,
:url => { :controller => 'submissions',
:action => :display_player_form },
:with => "'player='+value") %>
display_player_form.rjs:
page.replace_html 'observed_assay_form', :partial => 'submissions/player_form', :locals => {:submission => #submission }
Nothing is displayed!!
Am i missing something??
Thanks for helping me out with this :)
I finally figured it out. So here are my findings:
In the partial, include the form_for tag, just like in the original form--
<% form_for #object do |f| %>
In the action used when observing the field, in my case, 'display_player_form', create a new instance of the object(see below)
#object = Object.new
In your rjs file, enter the following:
page['id of div'].replace_html :partial => 'your_partial_name'
There you go...
Hope this helps
I would rename display_player_form.rjs to display_player_form.js.erb and have its contents look like this:
$("#observed_essay_form").html('<%=
escape_javascript(
render :partial => 'submissions/player_form', :locals => {:submission => #submission }
)
-%>');
$("img[src$='spinner.gif']:visible").hide(); // optional - hide any visible spinner.gif images
I use jQuery, not Prototype, by the way.
I currently am able to render a partial in JS like so:
$("#cmtList_<%= #commentable.id %>").prepend("<%=escape_javascript(render :partial =>"comments/comment", :locals => {:comment => #comment})%>");
The above works swell for rendering/returning one new comment.
Now I want to reuse that same partial(to stay DRY), but be able to pass an array of comments as #Comments, and have Rails loop through all the #comments records (1 or more) using the same partial, I tried this but it errors:
$("#cmtList_<%= #commentable.id %>").prepend("<%=escape_javascript(render :partial => "comments/comment", :collection => {:comment => #comments})%>");
Any ideas?
Thanks
Try this inside of escape_javascript:
render :partial => "comments/comment", :collection => #comments
Docs say that this should work too (too much magic for me):
render #comments
Check "3.4.5 Rendering Collections" from here:
http://guides.rubyonrails.org/layouts_and_rendering.html
Try:
$("#cmtList_<%= #commentable.id %>").prepend("<%=escape_javascript(render :partial => "comments/comment", :collection => #comments)%>");
which will look for a local variable "comment".
For more info: http://guides.rubyonrails.org/layouts_and_rendering.html
I render a partial like so:
<%= render :partial => 'widgets/some_partial, :locals => {:foo => 'bar'} %>
So inside of _some_partial.html.erb I render two more partials like so:
<% #foo.nil? #=> false %>
<%= render :partial => 'widgets/another_partial', :locals => {:foo => foo} %>
`<%= render :partial => 'widgets/another_partial_again', :locals => {:foo => foo} %>`
The foo local variable renders fine in some_partial.html.erb and even in another_partial_again.html.erb. However, the foo variable is inaccessible in another_partial.html.erb even though I explicitly passed it in the render call.
What is happening here?
Thanks for the help.
I had the undefined local variable or method error come up for me too when I was rendering a partial with :locals defined.
However, I had a different issue causing my problem, so I thought I would share my solution in case it helps anyone else. (This page was the first result when I googled this error after all)
Basically just make sure you use :partial => 'path/to/partial' in your call to render.
I.e.
<%= render :partial => 'widgets/some_partial', :locals => {:foo => 'bar'} %>
NOT like I was doing:
<%= render 'widgets/some_partial', :locals => {:foo => 'bar'} %>
Easy for a rails/ruby newbie like me to miss.
Solved. Turns out I was also rendering the same partial from the controller without sending the proper local variables. Thanks anyways!!!
Bumped into this very old question cause I faced the same issue.
Turned out that with Rails 4+ if you are not using collections or layout the correct way is:
# Instead of <%= render partial: "account", locals: { account: #buyer } %>
<%= render "account", account: #buyer %>
As documented here.