I have an ERB view with two blocks:
<%= test_h1 do %>
<%= 'test1' %>
<% end -%>
<%= test_h2 do %>
<%= 'test2' %>
<% end -%>
where test_h1
and test_h2
are similar helpers, but one is defined in a helper file, while another via helper_method
in a controller:
module TestHelper
def test_h1(&block)
link_to '/url' do
capture(&block)
end
end
end
class TestController < ApplicationController
helper_method :test_h2
def test_h2(&block)
helpers.link_to '/url' do
helpers.capture(&block)
end
end
end
test_h1
produces the expected result and test_h2
renders the inner template block first:
<a href="/url">test1</a>
test2<a href="/url"></a>
Why? What would be an idiomatic way to write test_h2
?
I think both examples of views should be re-written as:
<%= test_h1 do %>
<% 'test1' %>
<% end -%>
<%= test_h2 do %>
<% 'test2' %>
<% end -%>
My understanding that '<%=' forces to render the output of the block to the output stream, that was not an intended behavior in these two examples
capture
overrides current output buffer and just calls the block (which is still bound to other view context), thus override has no effect when called from controller because view_context
is not the same context the view is being rendered in.
To work around contexts you can define your helper like so:
# in controller
helper do
def test_h3(&block)
# this will run in view context, so call `controller.some_func` to access controller instance
link_to '/url' do
capture(&block)
end
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With