Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix very strange bug with form_for and capture_html (double render) #1177

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion padrino-helpers/lib/padrino-helpers/form_helpers.rb
Expand Up @@ -31,7 +31,8 @@ module FormHelpers
# @api public
def form_for(object, url, settings={}, &block)
instance = builder_instance(object, settings)
form_tag(url, settings) { capture_html(instance, &block) }
html = capture_html(instance, &block)
form_tag(url, settings) { html }
end

##
Expand Down
6 changes: 3 additions & 3 deletions padrino-helpers/lib/padrino-helpers/output_helpers.rb
Expand Up @@ -48,12 +48,12 @@ def render(engine, *) # @private
# @api semipublic
def capture_html(*args, &block)
handler = find_proper_handler
captured_html = ""
captured_block, captured_html = nil, ""
if handler && handler.is_type? && handler.block_is_type?(block)
captured_html = handler.capture_from_template(*args, &block)
captured_html, captured_block = handler.capture_from_template(*args, &block)
end
# invoking the block directly if there was no template
captured_html = block_given? && block.call(*args) if captured_html.blank?
captured_html = block_given? && ( captured_block || block.call(*args) ) if captured_html.blank?
captured_html
end
alias :capture :capture_html
Expand Down
Expand Up @@ -31,10 +31,10 @@ def is_type?
#
def capture_from_template(*args, &block)
self.output_buffer, _buf_was = ActiveSupport::SafeBuffer.new, self.output_buffer
block.call(*args)
captured_block = block.call(*args)
ret = eval("@_out_buf", block.binding)
self.output_buffer = _buf_was
ret
[ ret, captured_block ]
end

##
Expand Down
4 changes: 4 additions & 0 deletions padrino-helpers/test/fixtures/render_app/app.rb
Expand Up @@ -31,6 +31,10 @@ class RenderDemo < Padrino::Application
render :explicit_engine
end

get '/double_capture_:ext' do
render "double_capture_#{params[:ext]}"
end

# partial with object
get '/partial/object' do
partial 'template/user', :object => RenderUser.new('John'), :locals => { :extra => "bar" }
Expand Down
@@ -0,0 +1,3 @@
<% form_for( :object, '/' ) do |f| %>
<%= $number_of_captures += 1 %>
<% end %>
@@ -0,0 +1,2 @@
- form_for :object, '/' do |f|
= $number_of_captures += 1
@@ -0,0 +1,2 @@
- form_for :object, '/' do |f|
= $number_of_captures += 1
18 changes: 18 additions & 0 deletions padrino-helpers/test/test_render_helpers.rb
Expand Up @@ -72,5 +72,23 @@ def app
assert_have_selector 'p.slim span', :content => "slim"
assert_have_selector 'p.end', :content => "haml"
end

should "capture slim template once and only once" do
$number_of_captures = 0
visit '/double_capture_slim'
assert_equal 1,$number_of_captures
end

should "capture haml template once and only once" do
$number_of_captures = 0
visit '/double_capture_haml'
assert_equal 1,$number_of_captures
end

should "capture erb template once and only once" do
$number_of_captures = 0
visit '/double_capture_erb'
assert_equal 1,$number_of_captures
end
end
end