Skip to content
This repository
Browse code

Do not call fields_for from form_for, to avoid instantiating two buil…

…ders

Conflicts:
	actionpack/lib/action_view/helpers/form_helper.rb
	actionpack/test/template/form_helper_test.rb
commit 756188b512ca11e24262a74856e3bc11b9b2dbc9 1 parent 1506d4d
Carlos Antonio da Silva carlosantoniodasilva authored
14 actionpack/lib/action_view/helpers/form_helper.rb
@@ -331,9 +331,9 @@ def convert_to_model(object)
331 331 # In many cases you will want to wrap the above in another helper, so you
332 332 # could do something like the following:
333 333 #
334   - # def labelled_form_for(record_or_name_or_array, *args, &proc)
  334 + # def labelled_form_for(record_or_name_or_array, *args, &block)
335 335 # options = args.extract_options!
336   - # form_for(record_or_name_or_array, *(args << options.merge(:builder => LabellingFormBuilder)), &proc)
  336 + # form_for(record_or_name_or_array, *(args << options.merge(:builder => LabellingFormBuilder)), &block)
337 337 # end
338 338 #
339 339 # If you don't need to attach a form to a model instance, then check out
@@ -355,7 +355,7 @@ def convert_to_model(object)
355 355 # <%= form_for @invoice, :url => external_url, :authenticity_token => false do |f|
356 356 # ...
357 357 # <% end %>
358   - def form_for(record, options = {}, &proc)
  358 + def form_for(record, options = {}, &block)
359 359 raise ArgumentError, "Missing block" unless block_given?
360 360
361 361 options[:html] ||= {}
@@ -374,12 +374,10 @@ def form_for(record, options = {}, &proc)
374 374 options[:html][:method] = options.delete(:method) if options.has_key?(:method)
375 375 options[:html][:authenticity_token] = options.delete(:authenticity_token)
376 376
377   - builder = options[:parent_builder] = instantiate_builder(object_name, object, options, &proc)
378   - fields_for = fields_for(object_name, object, options, &proc)
  377 + builder = options[:parent_builder] = instantiate_builder(object_name, object, options, &block)
  378 + output = capture(builder, &block)
379 379 default_options = builder.multipart? ? { :multipart => true } : {}
380   - output = form_tag(options.delete(:url) || {}, default_options.merge!(options.delete(:html)))
381   - output << fields_for
382   - output.safe_concat('</form>')
  380 + form_tag(options.delete(:url) || {}, default_options.merge!(options.delete(:html))) { output }
383 381 end
384 382
385 383 def apply_form_for_options!(object_or_array, options) #:nodoc:
14 actionpack/test/template/form_helper_test.rb
@@ -755,7 +755,6 @@ def test_fields_for_with_file_field_generate_multipart
755 755 assert_dom_equal expected, output_buffer
756 756 end
757 757
758   -
759 758 def test_form_for_with_format
760 759 form_for(@post, :format => :json, :html => { :id => "edit_post_123", :class => "edit_post" }) do |f|
761 760 concat f.label(:title)
@@ -2217,6 +2216,19 @@ def test_fields_for_returns_block_result
2217 2216 assert_equal "fields", output
2218 2217 end
2219 2218
  2219 + def test_form_for_only_instantiates_builder_once
  2220 + initialization_count = 0
  2221 + builder_class = Class.new(ActionView::Helpers::FormBuilder) do
  2222 + define_method :initialize do |*args|
  2223 + super(*args)
  2224 + initialization_count += 1
  2225 + end
  2226 + end
  2227 +
  2228 + form_for(@post, :builder => builder_class) { }
  2229 + assert_equal 1, initialization_count, 'form builder instantiated more than once'
  2230 + end
  2231 +
2220 2232 protected
2221 2233 def protect_against_forgery?
2222 2234 false

0 comments on commit 756188b

Please sign in to comment.
Something went wrong with that request. Please try again.