Add an option to FormBuilder to omit hidden field with id

[#4551 state:committed]

Signed-off-by: Santiago Pastorino <santiago@wyeworks.com>
This commit is contained in:
Alexander Uvarov 2011-02-25 20:19:05 +05:00 committed by Santiago Pastorino
parent f00a398456
commit 0db915efd1
2 changed files with 157 additions and 2 deletions

View File

@ -262,6 +262,24 @@ module ActionView
# ...
# </form>
#
# === Removing hidden model id's
#
# The form_for method automatically includes the model id as a hidden field in the form.
# This is used to maintain the correlation between the form data and it's associated model.
# Some ORM systems do not use id's on nested models so in this case you want to be able
# to disable the hidden id.
#
# In the following example the Post model has many Comments stored within it in a NoSQL database,
# thus there is no primary key for comments.
#
# Example:
#
# <%= form(@post) do |f| %>
# <% f.fields_for(:comments, :include_id => false) do |cf| %>
# ...
# <% end %>
# <% end %>
#
# === Customized form builders
#
# You can also build forms using a customized FormBuilder class. Subclass
@ -332,7 +350,7 @@ module ActionView
options[:html][:remote] = options.delete(:remote)
options[:html][:authenticity_token] = options.delete(:authenticity_token)
builder = options[:parent_builder] = instantiate_builder(object_name, object, options, &proc)
fields_for = fields_for(object_name, object, options, &proc)
default_options = builder.multipart? ? { :multipart => true } : {}
@ -1326,7 +1344,9 @@ module ActionView
def fields_for_nested_model(name, object, options, block)
object = convert_to_model(object)
options[:hidden_field_id] = object.persisted?
parent_include_id = self.options.fetch(:include_id, true)
include_id = options.fetch(:include_id, parent_include_id)
options[:hidden_field_id] = object.persisted? && include_id
@template.fields_for(name, object, options, &block)
end

View File

@ -1103,6 +1103,61 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal expected, output_buffer
end
def test_nested_fields_for_with_an_existing_record_on_a_nested_attributes_one_to_one_association_with_disabled_hidden_id
@post.author = Author.new(321)
form_for(@post) do |f|
concat f.text_field(:title)
concat f.fields_for(:author, :include_id => false) { |af|
af.text_field(:name)
}
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
'<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />'
end
assert_dom_equal expected, output_buffer
end
def test_nested_fields_for_with_an_existing_record_on_a_nested_attributes_one_to_one_association_with_disabled_hidden_id_inherited
@post.author = Author.new(321)
form_for(@post, :include_id => false) do |f|
concat f.text_field(:title)
concat f.fields_for(:author) { |af|
af.text_field(:name)
}
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
'<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />'
end
assert_dom_equal expected, output_buffer
end
def test_nested_fields_for_with_an_existing_record_on_a_nested_attributes_one_to_one_association_with_disabled_hidden_id_override
@post.author = Author.new(321)
form_for(@post, :include_id => false) do |f|
concat f.text_field(:title)
concat f.fields_for(:author, :include_id => true) { |af|
af.text_field(:name)
}
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
'<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
'<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />'
end
assert_dom_equal expected, output_buffer
end
def test_nested_fields_for_with_existing_records_on_a_nested_attributes_one_to_one_association_with_explicit_hidden_field_placement
@post.author = Author.new(321)
@ -1146,6 +1201,86 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal expected, output_buffer
end
def test_nested_fields_for_with_existing_records_on_a_nested_attributes_collection_association_with_disabled_hidden_id
@post.comments = Array.new(2) { |id| Comment.new(id + 1) }
@post.author = Author.new(321)
form_for(@post) do |f|
concat f.text_field(:title)
concat f.fields_for(:author) { |af|
concat af.text_field(:name)
}
@post.comments.each do |comment|
concat f.fields_for(:comments, comment, :include_id => false) { |cf|
concat cf.text_field(:name)
}
end
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
'<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
'<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
'<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />'
end
assert_dom_equal expected, output_buffer
end
def test_nested_fields_for_with_existing_records_on_a_nested_attributes_collection_association_with_disabled_hidden_id_inherited
@post.comments = Array.new(2) { |id| Comment.new(id + 1) }
@post.author = Author.new(321)
form_for(@post, :include_id => false) do |f|
concat f.text_field(:title)
concat f.fields_for(:author) { |af|
concat af.text_field(:name)
}
@post.comments.each do |comment|
concat f.fields_for(:comments, comment) { |cf|
concat cf.text_field(:name)
}
end
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
'<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
'<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />'
end
assert_dom_equal expected, output_buffer
end
def test_nested_fields_for_with_existing_records_on_a_nested_attributes_collection_association_with_disabled_hidden_id_override
@post.comments = Array.new(2) { |id| Comment.new(id + 1) }
@post.author = Author.new(321)
form_for(@post, :include_id => false) do |f|
concat f.text_field(:title)
concat f.fields_for(:author, :include_id => true) { |af|
concat af.text_field(:name)
}
@post.comments.each do |comment|
concat f.fields_for(:comments, comment) { |cf|
concat cf.text_field(:name)
}
end
end
expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
'<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
'<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
'<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />'
end
assert_dom_equal expected, output_buffer
end
def test_nested_fields_for_with_existing_records_on_a_nested_attributes_collection_association_using_erb_and_inline_block
@post.comments = Array.new(2) { |id| Comment.new(id + 1) }