mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Fixed index and auto index for nested fields_for [#327 state:resolved]
Signed-off-by: Joshua Peek <josh@joshpeek.com>
This commit is contained in:
parent
706425e154
commit
1b4b1aa725
2 changed files with 136 additions and 10 deletions
|
@ -528,10 +528,10 @@ module ActionView
|
|||
|
||||
def initialize(object_name, method_name, template_object, object = nil)
|
||||
@object_name, @method_name = object_name.to_s.dup, method_name.to_s.dup
|
||||
@template_object= template_object
|
||||
@template_object = template_object
|
||||
@object = object
|
||||
if @object_name.sub!(/\[\]$/,"")
|
||||
if object ||= @template_object.instance_variable_get("@#{Regexp.last_match.pre_match}") and object.respond_to?(:to_param)
|
||||
if @object_name.sub!(/\[\]$/,"") || @object_name.sub!(/\[\]\]$/,"]")
|
||||
if (object ||= @template_object.instance_variable_get("@#{Regexp.last_match.pre_match}")) && object.respond_to?(:to_param)
|
||||
@auto_index = object.to_param
|
||||
else
|
||||
raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}"
|
||||
|
@ -708,7 +708,7 @@ module ActionView
|
|||
end
|
||||
|
||||
def sanitized_object_name
|
||||
@sanitized_object_name ||= @object_name.gsub(/[^-a-zA-Z0-9:.]/, "_").sub(/_$/, "")
|
||||
@sanitized_object_name ||= @object_name.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").sub(/_$/, "")
|
||||
end
|
||||
|
||||
def sanitized_method_name
|
||||
|
@ -726,6 +726,13 @@ module ActionView
|
|||
def initialize(object_name, object, template, options, proc)
|
||||
@object_name, @object, @template, @options, @proc = object_name, object, template, options, proc
|
||||
@default_options = @options ? @options.slice(:index) : {}
|
||||
if @object_name.to_s.match(/\[\]$/)
|
||||
if object ||= @template.instance_variable_get("@#{Regexp.last_match.pre_match}") and object.respond_to?(:to_param)
|
||||
@auto_index = object.to_param
|
||||
else
|
||||
raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
(field_helpers - %w(label check_box radio_button fields_for)).each do |selector|
|
||||
|
@ -738,16 +745,25 @@ module ActionView
|
|||
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
|
||||
|
||||
case record_or_name_or_array
|
||||
when String, Symbol
|
||||
name = "#{object_name}[#{record_or_name_or_array}]"
|
||||
name = "#{object_name}#{index}[#{record_or_name_or_array}]"
|
||||
when Array
|
||||
object = record_or_name_or_array.last
|
||||
name = "#{object_name}[#{ActionController::RecordIdentifier.singular_class_name(object)}]"
|
||||
name = "#{object_name}#{index}[#{ActionController::RecordIdentifier.singular_class_name(object)}]"
|
||||
args.unshift(object)
|
||||
else
|
||||
object = record_or_name_or_array
|
||||
name = "#{object_name}[#{ActionController::RecordIdentifier.singular_class_name(object)}]"
|
||||
name = "#{object_name}#{index}[#{ActionController::RecordIdentifier.singular_class_name(object)}]"
|
||||
args.unshift(object)
|
||||
end
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ silence_warnings do
|
|||
alias_method :title_before_type_cast, :title unless respond_to?(:title_before_type_cast)
|
||||
alias_method :body_before_type_cast, :body unless respond_to?(:body_before_type_cast)
|
||||
alias_method :author_name_before_type_cast, :author_name unless respond_to?(:author_name_before_type_cast)
|
||||
alias_method :secret?, :secret
|
||||
alias_method :secret?, :secret
|
||||
|
||||
def new_record=(boolean)
|
||||
@new_record = boolean
|
||||
|
@ -22,6 +22,7 @@ silence_warnings do
|
|||
attr_reader :post_id
|
||||
def save; @id = 1; @post_id = 1 end
|
||||
def new_record?; @id.nil? end
|
||||
def to_param; @id; end
|
||||
def name
|
||||
@id.nil? ? 'new comment' : "comment ##{@id}"
|
||||
end
|
||||
|
@ -30,7 +31,6 @@ end
|
|||
|
||||
class Comment::Nested < Comment; end
|
||||
|
||||
|
||||
class FormHelperTest < ActionView::TestCase
|
||||
tests ActionView::Helpers::FormHelper
|
||||
|
||||
|
@ -447,6 +447,117 @@ class FormHelperTest < ActionView::TestCase
|
|||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_nested_fields_for_with_nested_collections
|
||||
form_for('post[]', @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
f.fields_for('comment[]', @comment) do |c|
|
||||
concat c.text_field(:name)
|
||||
end
|
||||
end
|
||||
|
||||
expected = "<form action='http://www.example.com' method='post'>" +
|
||||
"<input name='post[123][title]' size='30' type='text' id='post_123_title' value='Hello World' />" +
|
||||
"<input name='post[123][comment][][name]' size='30' type='text' id='post_123_comment__name' value='new comment' />" +
|
||||
"</form>"
|
||||
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_nested_fields_for_with_index
|
||||
form_for('post', @post, :index => 1) do |c|
|
||||
concat c.text_field(:title)
|
||||
c.fields_for('comment', @comment, :index => 1) do |r|
|
||||
concat r.text_field(:name)
|
||||
end
|
||||
end
|
||||
|
||||
expected = "<form action='http://www.example.com' method='post'>" +
|
||||
"<input name='post[1][title]' size='30' type='text' id='post_1_title' value='Hello World' />" +
|
||||
"<input name='post[1][comment][1][name]' size='30' type='text' id='post_1_comment_1_name' value='new comment' />" +
|
||||
"</form>"
|
||||
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_nested_fields_for_with_index
|
||||
form_for(:post, @post, :index => 1) do |f|
|
||||
f.fields_for(:comment, @post) do |c|
|
||||
concat c.text_field(:title)
|
||||
end
|
||||
end
|
||||
|
||||
expected = "<form action='http://www.example.com' method='post'>" +
|
||||
"<input name='post[1][comment][title]' size='30' type='text' id='post_1_comment_title' value='Hello World' />" +
|
||||
"</form>"
|
||||
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_nested_fields_for_with_index_on_both
|
||||
form_for(:post, @post, :index => 1) do |f|
|
||||
f.fields_for(:comment, @post, :index => 5) do |c|
|
||||
concat c.text_field(:title)
|
||||
end
|
||||
end
|
||||
|
||||
expected = "<form action='http://www.example.com' method='post'>" +
|
||||
"<input name='post[1][comment][5][title]' size='30' type='text' id='post_1_comment_5_title' value='Hello World' />" +
|
||||
"</form>"
|
||||
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_nested_fields_for_with_auto_index
|
||||
form_for("post[]", @post) do |f|
|
||||
f.fields_for(:comment, @post) do |c|
|
||||
concat c.text_field(:title)
|
||||
end
|
||||
end
|
||||
|
||||
expected = "<form action='http://www.example.com' method='post'>" +
|
||||
"<input name='post[123][comment][title]' size='30' type='text' id='post_123_comment_title' value='Hello World' />" +
|
||||
"</form>"
|
||||
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_nested_fields_for_with_auto_index_on_both
|
||||
form_for("post[]", @post) do |f|
|
||||
f.fields_for("comment[]", @post) do |c|
|
||||
concat c.text_field(:title)
|
||||
end
|
||||
end
|
||||
|
||||
expected = "<form action='http://www.example.com' method='post'>" +
|
||||
"<input name='post[123][comment][123][title]' size='30' type='text' id='post_123_comment_123_title' value='Hello World' />" +
|
||||
"</form>"
|
||||
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_nested_fields_for_with_index_and_auto_index
|
||||
form_for("post[]", @post) do |f|
|
||||
f.fields_for(:comment, @post, :index => 5) do |c|
|
||||
concat c.text_field(:title)
|
||||
end
|
||||
end
|
||||
|
||||
form_for(:post, @post, :index => 1) do |f|
|
||||
f.fields_for("comment[]", @post) do |c|
|
||||
concat c.text_field(:title)
|
||||
end
|
||||
end
|
||||
|
||||
expected = "<form action='http://www.example.com' method='post'>" +
|
||||
"<input name='post[123][comment][5][title]' size='30' type='text' id='post_123_comment_5_title' value='Hello World' />" +
|
||||
"</form>" +
|
||||
"<form action='http://www.example.com' method='post'>" +
|
||||
"<input name='post[1][comment][123][title]' size='30' type='text' id='post_1_comment_123_title' value='Hello World' />" +
|
||||
"</form>"
|
||||
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_fields_for
|
||||
fields_for(:post, @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
|
@ -831,7 +942,6 @@ class FormHelperTest < ActionView::TestCase
|
|||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
|
||||
protected
|
||||
def comments_path(post)
|
||||
"/posts/#{post.id}/comments"
|
||||
|
|
Loading…
Reference in a new issue