mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Add index method to FormBuilder. Useful when you use field_for and need to know the index number into the iteration.
This commit is contained in:
parent
7ecd6a731b
commit
47cbfbb98a
3 changed files with 74 additions and 5 deletions
|
@ -1,5 +1,7 @@
|
|||
## Rails 4.0.0 (unreleased) ##
|
||||
|
||||
* Add `index` method to FormBuilder class. *Jorge Bejar*
|
||||
|
||||
* Remove the leading \n added by textarea on assert_select. *Santiago Pastorino*
|
||||
|
||||
* Changed default value for `config.action_view.embed_authenticity_token_in_remote_forms`
|
||||
|
|
|
@ -673,6 +673,19 @@ module ActionView
|
|||
# <% end %>
|
||||
# ...
|
||||
# <% end %>
|
||||
#
|
||||
# When a collection is used you might want to know the index of each
|
||||
# object into the array. For this purpose, the <tt>index</tt> method
|
||||
# is available in the FormBuilder object.
|
||||
#
|
||||
# <%= form_for @person do |person_form| %>
|
||||
# ...
|
||||
# <%= person_form.fields_for :projects do |project_fields| %>
|
||||
# Project #<%= project_fields.index %>
|
||||
# ...
|
||||
# <% end %>
|
||||
# ...
|
||||
# <% end %>
|
||||
def fields_for(record_name, record_object = nil, options = {}, &block)
|
||||
builder = instantiate_builder(record_name, record_object, options)
|
||||
output = capture(builder, &block)
|
||||
|
@ -1038,7 +1051,7 @@ module ActionView
|
|||
|
||||
attr_accessor :object_name, :object, :options
|
||||
|
||||
attr_reader :multipart, :parent_builder
|
||||
attr_reader :multipart, :parent_builder, :index
|
||||
alias :multipart? :multipart
|
||||
|
||||
def multipart=(multipart)
|
||||
|
@ -1076,6 +1089,7 @@ module ActionView
|
|||
end
|
||||
end
|
||||
@multipart = nil
|
||||
@index = options[:index] || options[:child_index]
|
||||
end
|
||||
|
||||
(field_helpers - [:label, :check_box, :radio_button, :fields_for, :hidden_field, :file_field]).each do |selector|
|
||||
|
@ -1107,12 +1121,14 @@ module ActionView
|
|||
end
|
||||
|
||||
index = if options.has_key?(:index)
|
||||
"[#{options[:index]}]"
|
||||
options[:index]
|
||||
elsif defined?(@auto_index)
|
||||
self.object_name = @object_name.to_s.sub(/\[\]$/,"")
|
||||
"[#{@auto_index}]"
|
||||
@auto_index
|
||||
end
|
||||
record_name = "#{object_name}#{index}[#{record_name}]"
|
||||
|
||||
record_name = index ? "#{object_name}[#{index}][#{record_name}]" : "#{object_name}[#{record_name}]"
|
||||
fields_options[:child_index] = index
|
||||
|
||||
@template.fields_for(record_name, record_object, fields_options, &block)
|
||||
end
|
||||
|
@ -1250,7 +1266,8 @@ module ActionView
|
|||
explicit_child_index = options[:child_index]
|
||||
output = ActiveSupport::SafeBuffer.new
|
||||
association.each do |child|
|
||||
output << fields_for_nested_model("#{name}[#{explicit_child_index || nested_child_index(name)}]", child, options, block)
|
||||
options[:child_index] = nested_child_index(name) unless explicit_child_index
|
||||
output << fields_for_nested_model("#{name}[#{options[:child_index]}]", child, options, block)
|
||||
end
|
||||
output
|
||||
elsif association
|
||||
|
|
|
@ -1835,6 +1835,56 @@ class FormHelperTest < ActionView::TestCase
|
|||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_nested_fields_for_index_method_with_existing_records_on_a_nested_attributes_collection_association
|
||||
@post.comments = Array.new(2) { |id| Comment.new(id + 1) }
|
||||
|
||||
form_for(@post) do |f|
|
||||
expected = 0
|
||||
@post.comments.each do |comment|
|
||||
f.fields_for(:comments, comment) { |cf|
|
||||
assert_equal cf.index, expected
|
||||
expected += 1
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_nested_fields_for_index_method_with_existing_and_new_records_on_a_nested_attributes_collection_association
|
||||
@post.comments = [Comment.new(321), Comment.new]
|
||||
|
||||
form_for(@post) do |f|
|
||||
expected = 0
|
||||
@post.comments.each do |comment|
|
||||
f.fields_for(:comments, comment) { |cf|
|
||||
assert_equal cf.index, expected
|
||||
expected += 1
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_nested_fields_for_index_method_with_existing_records_on_a_supplied_nested_attributes_collection
|
||||
@post.comments = Array.new(2) { |id| Comment.new(id + 1) }
|
||||
|
||||
form_for(@post) do |f|
|
||||
expected = 0
|
||||
f.fields_for(:comments, @post.comments) { |cf|
|
||||
assert_equal cf.index, expected
|
||||
expected += 1
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def test_nested_fields_for_index_method_with_child_index_option_override_on_a_nested_attributes_collection_association
|
||||
@post.comments = []
|
||||
|
||||
form_for(@post) do |f|
|
||||
f.fields_for(:comments, Comment.new(321), :child_index => 'abc') { |cf|
|
||||
assert_equal cf.index, 'abc'
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def test_nested_fields_uses_unique_indices_for_different_collection_associations
|
||||
@post.comments = [Comment.new(321)]
|
||||
@post.tags = [Tag.new(123), Tag.new(456)]
|
||||
|
|
Loading…
Reference in a new issue