Really fix merging of input collection

* Don't union the arrays
* Don't sort the arrays (in particular, HashWithIndifferentAccess has no <=>)
* Merge deeply nested collections
This commit is contained in:
Kamal Fariz Mahyuddin 2008-03-19 21:36:21 +08:00 committed by Bryan Helmkamp
parent 6861f3abf2
commit 3a272cef4e
2 changed files with 20 additions and 6 deletions

View File

@ -302,8 +302,8 @@ module ActionController
data.each do |key, value|
case form_data[form_number][key]
when Hash; then merge(form_data[form_number][key], value)
when Array; then form_data[form_number][key] = (form_data[form_number][key] | value).sort
when Hash, HashWithIndifferentAccess; then merge(form_data[form_number][key], value)
when Array; then form_data[form_number][key] += value
else form_data[form_number][key] = value
end
end
@ -311,9 +311,15 @@ module ActionController
def merge(a, b) # :nodoc:
a.keys.each do |k|
if b.has_key?(k) and Hash === a[k] and Hash === b[k]
a[k] = merge(a[k], b[k])
b.delete(k)
if b.has_key?(k)
case [a[k], b[k]].map(&:class)
when [Hash, Hash]
a[k] = merge(a[k], b[k])
b.delete(k)
when [Array, Array]
a[k] += b[k]
b.delete(k)
end
end
end
a.merge!(b)

View File

@ -203,11 +203,19 @@ class ClicksButtonTest < Test::Unit::TestCase
<input type="checkbox" name="options[]" value="burger" checked="checked" />
<input type="radio" name="options[]" value="fries" checked="checked" />
<input type="text" name="options[]" value="soda" />
<!-- Same value appearing twice -->
<input type="text" name="options[]" value="soda" />
<input type="hidden" name="options[]" value="dessert" />
<input type="hidden" name="response[choices][][selected]" value="one" />
<input type="hidden" name="response[choices][][selected]" value="two" />
<!-- Same value appearing twice -->
<input type="hidden" name="response[choices][][selected]" value="two" />
<input type="submit" />
</form>
EOS
@session.expects(:post_via_redirect).with("/login", "options" => ["burger", "dessert", "fries", "soda"])
@session.expects(:post_via_redirect).with("/login",
"options" => ["soda", "soda", "dessert", "burger", "fries"],
"response" => { "choices" => [{"selected" => "one"}, {"selected" => "two"}, {"selected" => "two"}]})
@session.clicks_button
end