From a3c55342838f953a15028b3abd99a1cbed3643e6 Mon Sep 17 00:00:00 2001 From: Jonathan Hyman Date: Wed, 27 Jul 2011 11:50:54 -0400 Subject: [PATCH] Updating params such that the symbol version returned recursively uses symbols as hash keys. That is, passing: /url?location[city]=Dallas&location[state]=TX will be available in the params hash as both * params[:location][:city] and params[:location][:state] * params['location']['city'] and params['location']['state'] --- lib/grape/endpoint.rb | 7 +++++- lib/grape/helpers/extensions/hash.rb | 12 ++++++++++ spec/grape/endpoint_spec.rb | 36 ++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 lib/grape/helpers/extensions/hash.rb diff --git a/lib/grape/endpoint.rb b/lib/grape/endpoint.rb index 2db50cc1b..9b1cf635b 100644 --- a/lib/grape/endpoint.rb +++ b/lib/grape/endpoint.rb @@ -1,5 +1,6 @@ require 'rack' require 'grape' +require File.dirname(__FILE__) + '/helpers/extensions/hash' module Grape # An Endpoint is the proxy scope in which all routing @@ -30,7 +31,11 @@ def self.call(env) def params @params ||= request.params.merge(env['rack.routing_args'] || {}).inject({}) do |h,(k,v)| h[k.to_s] = v - h[k.to_sym] = v + + # Also return a version of the parameters with symbols as hash keys + v_sym = (v.kind_of?(Hash) && v.respond_to?(:key_strings_to_symbols)) ? v.key_strings_to_symbols : v + h[k.to_sym] = v_sym + h end end diff --git a/lib/grape/helpers/extensions/hash.rb b/lib/grape/helpers/extensions/hash.rb new file mode 100644 index 000000000..3646601d1 --- /dev/null +++ b/lib/grape/helpers/extensions/hash.rb @@ -0,0 +1,12 @@ +class Hash + # Recursively replace key names that should be symbols with symbols. + def key_strings_to_symbols + new_hash = Hash.new + self.each_pair do |k,v| + new_value = (v.kind_of?(Hash) && v.respond_to?(:key_strings_to_symbols)) ? v.key_strings_to_symbols : v + new_key = k.kind_of?(String) ? k.to_sym : k + new_hash[new_key] = new_value + end + new_hash + end +end \ No newline at end of file diff --git a/spec/grape/endpoint_spec.rb b/spec/grape/endpoint_spec.rb index 3a90b0ca4..de5429b26 100644 --- a/spec/grape/endpoint_spec.rb +++ b/spec/grape/endpoint_spec.rb @@ -48,6 +48,42 @@ def app; subject end get '/hey/12' last_response.body.should == '12' end + + it 'returns a hashed version of parameters which are hashes with symbol keys' do + subject.get('/hey') do + "#{params[:location][:city]}, #{params[:location][:state]}" + end + + get '/hey?location[city]=New%20York&location[state]=NY' + last_response.body.should == "New York, NY" + end + + it 'returns a hashed version of parameters which are hashes with string keys' do + subject.get('/hey') do + "#{params['location']['city']}, #{params['location']['state']}" + end + + get '/hey?location[city]=New%20York&location[state]=NY' + last_response.body.should == "New York, NY" + end + + it 'returns a hashed version of parameters which are hashes with symbol keys multiple levels deep' do + subject.get('/hey') do + params[:location][:city][:neighborhood] + end + + get '/hey?location[city][neighborhood]=Chelsea' + last_response.body.should == "Chelsea" + end + + it 'returns a hashed version of parameters which are hashes with string keys multiple levels deep' do + subject.get('/hey') do + params['location']['city']['neighborhood'] + end + + get '/hey?location[city][neighborhood]=Chelsea' + last_response.body.should == "Chelsea" + end end describe '#error!' do