From 48b6bacbc534d4be3fa89bc19ea83c357a20e598 Mon Sep 17 00:00:00 2001 From: Edouard CHIN Date: Tue, 10 Jul 2018 22:34:02 -0400 Subject: e4e1b62 broke `to_param` handling: - There was an issue inside controller tests where order params were not respected, the reason was because we were calling `Hash#to_query` which sorts the results lexicographically. 1e4e1b62 fixed that issue by not using `to_query` but instead a utility function provided by rack. - However with the fix came another issue where it's now no longer possible to do this ``` post :foo, params: { user: User.first } # Prior to the patch the controller will receive { "user" => "1" } # Whereas now you get { "user": "#" } ``` The fix in this PR is to modify `Hash#to_query` to sort only when it doesn't contain an array structure that looks something like "bar[]" Ref https://github.com/rails/rails/pull/33341#issuecomment-404039396 --- activesupport/test/core_ext/object/to_query_test.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'activesupport/test/core_ext/object') diff --git a/activesupport/test/core_ext/object/to_query_test.rb b/activesupport/test/core_ext/object/to_query_test.rb index 7593bcfa4d..b0b7ef0913 100644 --- a/activesupport/test/core_ext/object/to_query_test.rb +++ b/activesupport/test/core_ext/object/to_query_test.rb @@ -77,6 +77,20 @@ class ToQueryTest < ActiveSupport::TestCase assert_equal "name=Nakshay&type=human", hash.to_query end + def test_hash_not_sorted_lexicographically_for_nested_structure + params = { + "foo" => { + "contents" => [ + { "name" => "gorby", "id" => "123" }, + { "name" => "puff", "d" => "true" } + ] + } + } + expected = "foo[contents][][name]=gorby&foo[contents][][id]=123&foo[contents][][name]=puff&foo[contents][][d]=true" + + assert_equal expected, URI.decode(params.to_query) + end + private def assert_query_equal(expected, actual) assert_equal expected.split("&"), actual.to_query.split("&") -- cgit v1.2.3