I have a model Session
, which has_many
ExperimentSessions
. In sessions/show.js.erb
I render a Session
's ExperimentSessions
using a partial:
#/sessions/show.js.erb
<% out = '' %>
<% fields_for @session do |sess_f| %>
<% sess_f.fields_for :experiment_sessions, child_index: "", index:nil do |f| %>
<% out += j "<li class='list-group-item'>"%>
<% out += j render partial: 'experiment_sessions/exp_sess', locals: {f:f} %>
<% out += j "</li>"%>
<% end %>
<% end %>
This works well. However, I'd like to put this into its own partial view to reuse it. I have this:
#/sessions/_exp_sessions_li.html.erb
<% fields_for session do |sess_f| %>
<% sess_f.fields_for :experiment_sessions, child_index: "", index:nil do |f| %>
<%= "<li class='list-group-item'>"%>
<%= render partial: 'experiment_sessions/exp_sess', locals: {f:f} %>
<%= "</li>"%>
<% end%>
<% end %>
and include it in show.js.erb
:
#/sessions/show.js.erb
<% out = j(render(partial: 'exp_sessions_li', locals: {session: @session} )) %>
From the logs, there are no errors, and the partials get rendered. However, out
is the empty string.
Why does _exp_sessions_li.html.erb
produce empty output?
Edit: clarify logs
logger.ap @session
output in show.js.erb
:
#<Session:0x007fc4859748d8> {
:id => 732187210,
:recorded_on => Fri, 20 Mar 2015 00:00:00 EDT -04:00,
:notes => "session_j_b_ 15",
:created_at => Fri, 20 Mar 2015 00:00:00 EDT -04:00,
:updated_at => Fri, 20 Mar 2015 00:00:00 EDT -04:00
}
logger.ap @session.experiment_sessions
shows these objects as well. session
is also visible as expected in /sessions/_exp_sessions_li.html.erb
.
Log indicates the partials get rendered:
Rendered experiment_sessions/_exp_sess.html.erb (0.7ms)
Rendered experiment_sessions/_exp_sess.html.erb (0.6ms)
Rendered sessions/_exp_sessions_li.html.erb (4.9ms)
Edit: drill down on partial
Replacing the contents of _exp_sessions_li.html.erb
with a string will render that string. Furthermore, if I edit this file to be
aa
<% fields_for session do |sess_f| %>
bb
<% sess_f.fields_for :experiment_sessions, child_index: "", index:nil do |f| %>
cc
<%= "<li class='list-group-item'>"%>
<%= render partial: 'experiment_sessions/exp_sess', locals: {f:f} %>
[...]
will only show 'aa
' in out
. So fields_for
seems to eat the output. Note that the logs still say exp_sess
gets rendered.
Now, if I write <%= fields_for session do |sess_f| %>
, output also contains 'bb
'. And adding <%= sess_f.fields_for ...
also the rest. The raw HTML parts (<li ..
) are escaped, however.
OK, my mistake was to not return the output of the
fields_for
blocks.The reason my original code works is that I add the output of every line to my output variable (including output of
j
calls, which were the only reason the<li ...
lines were sent through ruby in the first place).Simply writing
<%= fields_for
… solves my issue.