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:
parent
6861f3abf2
commit
3a272cef4e
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user