From 766cdb5872ee934518b544175aca7d24d5746f71 Mon Sep 17 00:00:00 2001 From: Nicolas Klein Date: Mon, 10 Dec 2018 20:34:02 +0000 Subject: [PATCH] Allows to set a global ParamBuilder (#1833) --- CHANGELOG.md | 1 + README.md | 30 ++++++++++++++++++++++++++++-- lib/grape.rb | 2 +- lib/grape/config.rb | 32 ++++++++++++++++++++++++++++++++ lib/grape/request.rb | 2 +- spec/grape/config_spec.rb | 17 +++++++++++++++++ spec/grape/request_spec.rb | 24 ++++++++++++++++++++++++ 7 files changed, 104 insertions(+), 4 deletions(-) create mode 100644 lib/grape/config.rb create mode 100644 spec/grape/config_spec.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 062a9643a..575ebb641 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ #### Features * Your contribution here. +* [#1833](https://github.com/ruby-grape/grape/pull/1833): Allows to set the `ParamBuilder` globally - [@myxoh](https://github.com/myxoh). #### Fixes diff --git a/README.md b/README.md index 0038234dd..6d0d6721a 100644 --- a/README.md +++ b/README.md @@ -22,13 +22,14 @@ - [Rails](#rails) - [Modules](#modules) - [Remounting](#remounting) - - [Configuration](#configuration) + - [Mount Configuration](#mount-configuration) - [Versioning](#versioning) - [Path](#path) - [Header](#header) - [Accept-Version Header](#accept-version-header) - [Param](#param) - [Describing Methods](#describing-methods) +- [Configuration](#configuration) - [Parameters](#parameters) - [Params Class](#params-class) - [Declared](#declared) @@ -395,7 +396,7 @@ end Assuming that the post and comment endpoints are mounted in `/posts` and `/comments`, you should now be able to do `get /posts/votes`, `post /posts/votes`, `get /comments/votes`. -### Configuration +### Mount Configuration You can configure remountable endpoints for small details changing according to where they are mounted. @@ -541,6 +542,29 @@ end [grape-swagger]: https://github.com/ruby-grape/grape-swagger +## Configuration + +Use `Grape.configure` to set up global settings at load time. +Currently the configurable settings are: + +* `param_builder`: Sets the [Parameter Builder](#parameters), defaults to `Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder`. + +To change a setting value make sure that at some point on load time the code the following code runs + +```ruby +Grape.configure do |config| + config.setting = value +end +``` + +For example, for the `param_builder`, the following code could run in an initializers: + +```ruby +Grape.configure do |config| + config.param_builder = Grape::Extensions::Hashie::Mash::ParamBuilder +end +``` + ## Parameters Request parameters are available through the `params` hash object. This includes `GET`, `POST` @@ -618,6 +642,8 @@ params do end ``` +Or globally with the [Configuration](#configuration) `Grape.configure.param_builder`. + In the example above, `params["color"]` will return `nil` since `params` is a plain `Hash`. Available parameter builders are `Grape::Extensions::Hash::ParamBuilder`, `Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder` and `Grape::Extensions::Hashie::Mash::ParamBuilder`. diff --git a/lib/grape.rb b/lib/grape.rb index d626ec5c0..90597562d 100644 --- a/lib/grape.rb +++ b/lib/grape.rb @@ -34,7 +34,6 @@ module Grape autoload :Namespace autoload :Path - autoload :Cookies autoload :Validations autoload :ErrorFormatter @@ -194,6 +193,7 @@ module ServeFile end end +require 'grape/config' require 'grape/util/content_types' require 'grape/validations/validators/base' diff --git a/lib/grape/config.rb b/lib/grape/config.rb new file mode 100644 index 000000000..a1ebb706a --- /dev/null +++ b/lib/grape/config.rb @@ -0,0 +1,32 @@ +module Grape + module Config + class Configuration + ATTRIBUTES = %i[ + param_builder + ].freeze + + attr_accessor(*ATTRIBUTES) + + def initialize + reset + end + + def reset + self.param_builder = Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder + end + end + + def self.extended(base) + def base.configure + block_given? ? yield(config) : config + end + + def base.config + @configuration ||= Grape::Config::Configuration.new + end + end + end +end + +Grape.extend Grape::Config +Grape.config.reset diff --git a/lib/grape/request.rb b/lib/grape/request.rb index 0f11dff9e..7209a60d0 100644 --- a/lib/grape/request.rb +++ b/lib/grape/request.rb @@ -5,7 +5,7 @@ class Request < Rack::Request alias rack_params params def initialize(env, options = {}) - extend options[:build_params_with] || Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder + extend options[:build_params_with] || Grape.config.param_builder super(env) end diff --git a/spec/grape/config_spec.rb b/spec/grape/config_spec.rb new file mode 100644 index 000000000..f9290e3c7 --- /dev/null +++ b/spec/grape/config_spec.rb @@ -0,0 +1,17 @@ +require 'spec_helper' + +describe '.configure' do + before do + Grape.configure do |config| + config.param_builder = 42 + end + end + + after do + Grape.config.reset + end + + it 'is configured to the new value' do + expect(Grape.config.param_builder).to eq 42 + end +end diff --git a/spec/grape/request_spec.rb b/spec/grape/request_spec.rb index b763532ca..2c352d175 100644 --- a/spec/grape/request_spec.rb +++ b/spec/grape/request_spec.rb @@ -62,6 +62,30 @@ module Grape end end + describe 'when the param_builder is set to Hashie' do + before do + Grape.configure do |config| + config.param_builder = Grape::Extensions::Hashie::Mash::ParamBuilder + end + end + + after do + Grape.config.reset + end + + subject(:request_params) { Grape::Request.new(env, opts).params } + + context 'when the API does not include a specific param builder' do + let(:opts) { {} } + it { is_expected.to be_a(Hashie::Mash) } + end + + context 'when the API includes a specific param builder' do + let(:opts) { { build_params_with: Grape::Extensions::Hash::ParamBuilder } } + it { is_expected.to be_a(Hash) } + end + end + describe '#headers' do let(:options) do default_options.merge(request_headers)