Permalink
Browse files

Refactor fields_for to make the api more clear, and fix usage with no…

…n nested attributes and without object
  • Loading branch information...
1 parent 6871cda commit f0479cbbd52961c75906022003d4f03aa39556e0 @carlosantoniodasilva carlosantoniodasilva committed May 14, 2011
Showing with 33 additions and 26 deletions.
  1. +19 −26 actionpack/lib/action_view/helpers/form_helper.rb
  2. +14 −0 actionpack/test/template/form_helper_test.rb
@@ -1216,35 +1216,30 @@ def #{selector}(method, options = {}) # def text_field(method, options = {})
RUBY_EVAL
end
- def fields_for(record_or_name_or_array, *args, &block)
- if options.has_key?(:index)
- index = "[#{options[:index]}]"
- elsif defined?(@auto_index)
- self.object_name = @object_name.to_s.sub(/\[\]$/,"")
- index = "[#{@auto_index}]"
- else
- index = ""
- end
-
- args << {} unless args.last.is_a?(Hash)
- args.last[:builder] ||= options[:builder]
- args.last[:parent_builder] = self
+ def fields_for(record_name, record_object = nil, fields_options = {}, &block)
+ fields_options, record_object = record_object, nil if record_object.is_a?(Hash)
+ fields_options[:builder] ||= options[:builder]
+ fields_options[:parent_builder] = self
- case record_or_name_or_array
+ case record_name
when String, Symbol
- if nested_attributes_association?(record_or_name_or_array)
- return fields_for_with_nested_attributes(record_or_name_or_array, args, block)
- else
- name = record_or_name_or_array
+ if nested_attributes_association?(record_name)
+ return fields_for_with_nested_attributes(record_name, record_object, fields_options, block)
end
else
- object = record_or_name_or_array.is_a?(Array) ? record_or_name_or_array.last : record_or_name_or_array
- name = ActiveModel::Naming.param_key(object)
- args.unshift(object)
+ record_object = record_name.is_a?(Array) ? record_name.last : record_name
+ record_name = ActiveModel::Naming.param_key(record_object)
+ end
+
+ index = if options.has_key?(:index)
+ "[#{options[:index]}]"
+ elsif defined?(@auto_index)
+ self.object_name = @object_name.to_s.sub(/\[\]$/,"")
+ "[#{@auto_index}]"
end
- name = "#{object_name}#{index}[#{name}]"
+ record_name = "#{object_name}#{index}[#{record_name}]"
- @template.fields_for(name, *args, &block)
+ @template.fields_for(record_name, record_object, fields_options, &block)
end
def label(method, text = nil, options = {}, &block)
@@ -1333,10 +1328,8 @@ def nested_attributes_association?(association_name)
@object.respond_to?("#{association_name}_attributes=")
end
- def fields_for_with_nested_attributes(association_name, args, block)
+ def fields_for_with_nested_attributes(association_name, association, options, block)
name = "#{object_name}[#{association_name}_attributes]"
- options = args.extract_options!
- association = args.shift
association = convert_to_model(association)
if association.respond_to?(:persisted?)
@@ -1725,6 +1725,20 @@ def test_form_for_and_fields_for_with_object
assert_dom_equal expected, output_buffer
end
+ def test_form_for_and_fields_for_with_non_nested_association_and_without_object
+ form_for(@post) do |f|
+ concat f.fields_for(:category) { |c|
+ concat c.text_field(:name)
+ }
+ end
+
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', 'put') do
+ "<input name='post[category][name]' type='text' size='30' id='post_category_name' />"
+ end
+
+ assert_dom_equal expected, output_buffer
+ end
+
class LabelledFormBuilder < ActionView::Helpers::FormBuilder
(field_helpers - %w(hidden_field)).each do |selector|
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1

0 comments on commit f0479cb

Please sign in to comment.