mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Refactor fields_for to make the api more clear, and fix usage with non nested attributes and without object
This commit is contained in:
parent
6871cda693
commit
f0479cbbd5
2 changed files with 33 additions and 26 deletions
|
@ -1216,35 +1216,30 @@ module ActionView
|
|||
RUBY_EVAL
|
||||
end
|
||||
|
||||
def fields_for(record_or_name_or_array, *args, &block)
|
||||
if options.has_key?(:index)
|
||||
index = "[#{options[:index]}]"
|
||||
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_name
|
||||
when String, Symbol
|
||||
if nested_attributes_association?(record_name)
|
||||
return fields_for_with_nested_attributes(record_name, record_object, fields_options, block)
|
||||
end
|
||||
else
|
||||
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(/\[\]$/,"")
|
||||
index = "[#{@auto_index}]"
|
||||
else
|
||||
index = ""
|
||||
"[#{@auto_index}]"
|
||||
end
|
||||
record_name = "#{object_name}#{index}[#{record_name}]"
|
||||
|
||||
args << {} unless args.last.is_a?(Hash)
|
||||
args.last[:builder] ||= options[:builder]
|
||||
args.last[:parent_builder] = self
|
||||
|
||||
case record_or_name_or_array
|
||||
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
|
||||
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)
|
||||
end
|
||||
name = "#{object_name}#{index}[#{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 @@ module ActionView
|
|||
@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 @@ class FormHelperTest < ActionView::TestCase
|
|||
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
|
||||
|
|
Loading…
Reference in a new issue