Why is this block not working on my ERB template - ruby-on-rails

<%= render layout: "shared/some_template",
locals: {
variable_value: true
} do %>
<%= hidden_field_tag "ids[]", "ng-value": "sth.id" %>
<% end %>
The template on some template has some html and a yield call where the "hidden" field should go but it's not rendering it, it does render everything else inside the template, it just drops the hidden_field_tag part.
Any idea how can I solve this? it works on the HAML version when I tried it, but not on ERB, is that not available for ERB?

You are passing a &block to render, which is doing nothing with it.
To pass a callback to a partial, build a lambda and put it in a local variable:
<%=
lamb = lambda{ hidden_field_tag 'ids[]', 'ng-value' => 'sth.id' }
locals = { variable_value: true, callback: lamb }
render layout: 'shared/some_template', locals: locals
%>
Now inside the template call <%= callback.call %>.
(Note, BTW, that I used ' instead of ", because we are not using the special features of ". And note I introduced a local variable, locals, instead of creatively indenting the render call.)

Related

rails: pass variable to partial

How can I pass a variable to a partial using this code? :
<%= render #performance_indicator.improvement_actions.order("created_at DESC") %>
I want to pass "id=1" and then in _improvement_action, use that variable like:
<%= id %>
EDIT:
This is my improvement_action partial:
https://gist.github.com/luisamaro0/6597084f2de1dc33cde7c014ea9f23a5
You can pass a local variable like so:
render "a_partial", :a_local_variable => whatever, :another_variable => another
See this question for more details: Rails 3, passing local variable to partial
you can pass a variable like this
<%= render partial: 'partial_name', locals: {id: '1'} %>
Try this syntax out:
<%= render #performance_indicator.improvement_actions, locals: { local_variable: 1 %>
# then <%= local_variable %>

Rails + Bootstrap: Render partial with locals in Bootstrap popover

I want to pass a local variable to my partial when I render it in a Bootstrap popover. Here's what I've got, though I'm pretty sure I'm not rendering the partial correctly in the content_tag.
<%= content_tag :button, type: "button", class: "btn btn-default",
:data => { container: "body", toggle: "popover", placement: "bottom",
content: "#{render 'layouts/quick_add_form', :locals => {:code => item1.code}}"} do %>
button
<% end %>
Any help is much appreciated!
EDIT
Currently the local variable is not being passed to the partial, and so the :code attribute is not saved on form submit.
I don't believe you can use #{} except in HAML (oh wait, I see #{} is used as regular Ruby string interpolation - I think it will work). Not only that, but when you call render on a partial and you want to pass additional values, for some reason (for some versions of Rails), you have to explicitely declare it a partial:
render partial: 'layouts/quick_add_form', :locals => {:code => item1.code}
That will work, at least in an ERB or HAML.
You should also verify the generated HTML is escaped properly in the data attribute by viewing CTRL-U source in the browser.

Ruby on Rails pass reference to yield (template)

To make long story short: each of my tabs has its own form, so I decided to make a single layout and just to have a forms themselves as a variable content for a layout.
But I need to have form_for to be in a layout, rather then having it in each of the forms, because I have some other common form elements in the layout.
So how can I pass the form builder's reference f to the template ?
Layout code:
<% content_for(:content) do %>
<%= form_for current_form do |f| %>
<%= yield %>
<%= f.submit "Submit" %>
<% end %>
<% end %>
Is it possible ?
P.S Found this one: DRYing up a helper: wrap form_for and access local form variable (#rubish's answer), but <%= yield f %> doesn't seem to be working, f still remains undefined for the view.
Why don't you make a common template (not layout) for the tabs, and use a partial template for the content of each tab?
Then you can do something like:
<%= render :partial => #tab_name, :locals => {:form => f} %>
You can render a template in Rails that accepts a block by using the layout option of render
Let's say you have a form that you render a few times but you would like to customize your submit section each time. You can achieve this by rendering your form partial as layout and passing in a block. Your template or partial then serves as the surrounding layout of the block that you pass in. You can then yield back the form to the block and access the form in your block.
record/_form.haml
= form_for record do |form|
...
.form-actions
yield(form)
In order to make your template record/_form.haml accept a block when you render it, you can render your template as the layout for your block using the layout option of render:
record/edit.haml
= render layout: 'form', locals: { record: record, ... } do |form|
.form-actions--primary
= form.button :submit

Pass Parameters in render - Rails 3

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.
try this:
<%= render :partial => '/memory_books/new', :locals => {:fbookupload => "yes"} %>
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 ...
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 %>
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.
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.

Handling an undefined variable

I render a partial in one view:
<%= render 'video', :video => #video, :video_id => 'video_show_id' %>
and have this code in the partial:
<% if video_id %>
<%= link_to "video", video.video_url, :class => "oembed", :id => video_id %>
<% else %>
<%= link_to "video", video.video_url, :class => "oembed" %>
<% end %>
The problem is that this partial gets rendered in a number of places in my app, and in those other views I do not want to pass :video_id into the partial. Therefore my app throws an error that video_id is undefined. I could pass :video_id => "" into the partial in the other views, but since the partial is rendered in many places, that is kind of a pain. Is there a simpler way to handle this?
Try defined? and not that it really matters but it's actually an operator.
<% if defined? video_id %>
I think the better way to handle this is to create a helper that then manages the values of variables that need to fed to a partial. Something like:
module VideoHelper
def show_video(video, options = {})
options[:id] ||= ""
render 'video', :video => video, :video_id => options[:id]
end
end
Now, instead of having to have that long render partial line in your view, you get to shorten it to a show_video call.
Also, I've found that in the long term, this allows for a lot more flexibility and I have to think a lot less about what variables the partial needs at this time and whether or not they are defined.
Change the check to <% if defined? video_id %>

Resources