From 0ae3608c21e4d2da9d44a4762d0f632f7ef8184b Mon Sep 17 00:00:00 2001 From: dblock Date: Sun, 9 Apr 2017 17:45:09 -0400 Subject: [PATCH] Fix: in Rails 3 HashWithIndifferentAccess doesn't convert nested Hashes. --- lib/grape.rb | 1 + .../hash_with_indifferent_access.rb | 19 ++++++++++--------- .../deep_hash_with_indifferent_access.rb | 18 ++++++++++++++++++ lib/grape/extensions/deep_symbolize_hash.rb | 10 +++++++++- 4 files changed, 38 insertions(+), 10 deletions(-) create mode 100644 lib/grape/extensions/deep_hash_with_indifferent_access.rb diff --git a/lib/grape.rb b/lib/grape.rb index e5e9e7636f..932ef5107c 100644 --- a/lib/grape.rb +++ b/lib/grape.rb @@ -82,6 +82,7 @@ module Extensions autoload :DeepMergeableHash autoload :DeepSymbolizeHash + autoload :DeepHashWithIndifferentAccess autoload :Hash module ActiveSupport diff --git a/lib/grape/extensions/active_support/hash_with_indifferent_access.rb b/lib/grape/extensions/active_support/hash_with_indifferent_access.rb index 291e34decd..c6bf2ca1aa 100644 --- a/lib/grape/extensions/active_support/hash_with_indifferent_access.rb +++ b/lib/grape/extensions/active_support/hash_with_indifferent_access.rb @@ -2,21 +2,22 @@ module Grape module Extensions module ActiveSupport module HashWithIndifferentAccess - extend ::ActiveSupport::Concern + module ParamBuilder + extend ::ActiveSupport::Concern - included do - namespace_inheritable(:build_params_with, Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder) - end + included do + namespace_inheritable(:build_params_with, Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder) + end - def params_builder - Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder - end + def params_builder + Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder + end - module ParamBuilder def build_params params = ::ActiveSupport::HashWithIndifferentAccess[rack_params] params.deep_merge!(grape_routing_args) if env[Grape::Env::GRAPE_ROUTING_ARGS] - params + # TODO: remove, in Rails 4 or later ::ActiveSupport::HashWithIndifferentAccess converts nested Hashes into indifferent access ones + DeepHashWithIndifferentAccess.deep_hash_with_indifferent_access(params) end end end diff --git a/lib/grape/extensions/deep_hash_with_indifferent_access.rb b/lib/grape/extensions/deep_hash_with_indifferent_access.rb new file mode 100644 index 0000000000..e18601f8d8 --- /dev/null +++ b/lib/grape/extensions/deep_hash_with_indifferent_access.rb @@ -0,0 +1,18 @@ +module Grape + module Extensions + module DeepHashWithIndifferentAccess + def self.deep_hash_with_indifferent_access(object) + case object + when ::Hash + object.inject(::ActiveSupport::HashWithIndifferentAccess.new) do |new_hash, (key, value)| + new_hash.merge!(key => deep_hash_with_indifferent_access(value)) + end + when ::Array + object.map { |element| deep_hash_with_indifferent_access(element) } + else + object + end + end + end + end +end diff --git a/lib/grape/extensions/deep_symbolize_hash.rb b/lib/grape/extensions/deep_symbolize_hash.rb index 8c54ebc46c..310a658af1 100644 --- a/lib/grape/extensions/deep_symbolize_hash.rb +++ b/lib/grape/extensions/deep_symbolize_hash.rb @@ -15,7 +15,15 @@ def self.deep_symbolize_keys_in(object) end def self.symbolize_key(key) - key.respond_to?(:to_sym) ? key.to_sym : key + if key.is_a?(Symbol) + key + elsif key.is_a?(String) + key.to_sym + elsif key.respond_to?(:to_sym) + key.to_sym + else + key + end end end end