Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Added support for nested hashes #84

Closed
wants to merge 3 commits into from

3 participants

@mariochavez

Without this Weary can't be upgraded to latest addressable gem version

So now we can pass to query_values a hash like:

{:public=>true, :files=>{"file1.txt"=>{:content=>"String file contents"}}}

And get it converted to:

{"public"=>true, "files[file1.txt][content]"=>"String file contents"}

Which query_params will finally convert to:

["flag1=value1", "flag2%5Bflag3%5D%5Bflag4%5D=value2"] or ["flag1=value1", "flag2[flag3][flag4]=value2"]

But this change broke the following tests where the hashes have become valid:
1) Addressable::URI when assigning query values should raise an error attempting to assign {'a' => {'b' => ['c']}}
Failure/Error: (lambda do
expected TypeError but nothing was raised
# ./spec/addressable/uri_spec.rb:4925:in `block (2 levels) in '

2) Addressable::URI when assigning query values should raise an error attempting to assign {:b => '2', :a => {:c => '1'}}
Failure/Error: (lambda do
expected TypeError but nothing was raised
# ./spec/addressable/uri_spec.rb:4932:in `block (2 levels) in '

3) Addressable::URI when assigning query values should raise an error attempting to assign {:a => 'a', :b => {:c => true, :d => 'd'}}
Failure/Error: (lambda do
expected TypeError but nothing was raised
# ./spec/addressable/uri_spec.rb:4959:in `block (2 levels) in '

4) Addressable::URI when assigning query values should raise an error attempting to assign {:a => 'a', :b => {:c => true, :d => 'd'}}
Failure/Error: (lambda do
expected TypeError but nothing was raised
# ./spec/addressable/uri_spec.rb:4968:in `block (2 levels) in '

{"a"=>{"b"=>["c"]}} => {"a[b]"=>["c"]}
{:b => '2', :a => {:c => '1'}} => {"b"=>"2", "a[c]"=>"1"}
{:a=>"a", :b=>{:c=>true, :d=>"d"}} => {"a"=>"a", "b[c]"=>true, "b[d]"=>"d"}
{:a => 'a', :b => {:c => true, :d => 'd'}} => {"a"=>"a", "b[c]"=>true, "b[d]"=>"d"}

Please advice if this patch is ok and if I should just delete failed tests since their test cases are not valid anymore with this patch.

@travisbot

This pull request fails (merged 27c7f56 into ee198d4).

@sporkmonger
Owner

Provisionally closing this as I won't accept pull requests with failing tests under any circumstances. This issue has already been covered in #77.

I'm somewhat open to solutions that support nested hashes as input with the understanding that these would be normalized to the currently supported flattened form and completely unsupported on the parsing side of things. However, I remain reluctant even there because, as I've said elsewhere, I think nested structures being shoved into query parameters are a bad idea generally.

@sporkmonger sporkmonger closed this
@artempartos artempartos referenced this pull request in mwunsch/weary
Merged

Resource nested hash support #42

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Aug 7, 2012
  1. @mariochavez

    Added support for nested hashes, without this Weary can't be

    mariochavez authored
    upgraded to latest addressable gem version
  2. @mariochavez
  3. @mariochavez

    Fixed a case of convertion from symbol to string way before, causing …

    mariochavez authored
    …a hash
    
    to lost keys like in the case of "a" and :a
This page is out of date. Refresh to see the latest.
Showing with 22 additions and 0 deletions.
  1. +15 −0 lib/addressable/uri.rb
  2. +7 −0 spec/addressable/uri_spec.rb
View
15 lib/addressable/uri.rb
@@ -1491,6 +1491,7 @@ def query_values=(new_query_values)
"Can't convert #{new_query_values.class} into Hash."
end
new_query_values = new_query_values.to_hash
+ new_query_values = flatten_keys new_query_values
new_query_values = new_query_values.map do |key, value|
key = key.to_s if key.kind_of?(Symbol)
[key, value]
@@ -1525,6 +1526,20 @@ def query_values=(new_query_values)
self.query = buffer.chop
end
+ def flatten_keys hash, keys=nil
+ new_hash = {}
+ hash.map do |k, v|
+ new_keys = keys ? "#{keys}[#{k.to_s}]" : k
+ if v.is_a?(Hash)
+ sub_hash = flatten_keys v, new_keys
+ new_hash.merge! sub_hash
+ else
+ new_hash.merge! new_keys => v
+ end
+ end
+ new_hash
+ end
+
##
# The HTTP request URI for this URI. This is the path and the
# query string.
View
7 spec/addressable/uri_spec.rb
@@ -2933,6 +2933,13 @@ def to_s
}
end
+ it "should have the correct query string after multilevel hash assignment" do
+ @uri.query_values = {:flag1 => 'value1', :flag2 => {:flag3 => {:flag4 => 'value2'}}}
+ @uri.query.split("&").should include("flag1=value1")
+ @uri.query.split("&").should include("flag2%5Bflag3%5D%5Bflag4%5D=value2")
+ @uri.query_values(Array).sort.should == [["flag1", "value1"], ["flag2[flag3][flag4]", "value2"]]
+ end
+
it "should have the correct query string after flag hash assignment" do
@uri.query_values = {'flag?1' => true, 'fl=ag2' => true, 'flag3' => true}
@uri.query.split("&").should include("flag%3F1")
Something went wrong with that request. Please try again.