Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allows to set a global ParamBuilder #1833

Merged
merged 15 commits into from
Dec 10, 2018
Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -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).
* [#1832](https://github.com/ruby-grape/grape/pull/1832): Support `body_name` in `desc` block - [@fotos](https://github.com/fotos).
* [#1831](https://github.com/ruby-grape/grape/pull/1831): Support `security` in `desc` block - [@fotos](https://github.com/fotos).

Expand Down
30 changes: 28 additions & 2 deletions README.md
Expand Up @@ -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)
Expand Down Expand Up @@ -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.

Expand Down Expand Up @@ -541,6 +542,29 @@ end

[grape-swagger]: https://github.com/ruby-grape/grape-swagger

## Configuration

Grape counts with a module `Grape::Config` for some basic configuration at load time.
Currently the configurable settings are:

* `param_builder`: Sets the default [Parameter Builder](#parameters), by default: `Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sets the Parameter Builder, 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::Config.configure do |config|
myxoh marked this conversation as resolved.
Show resolved Hide resolved
config.setting = value
end
```

For example, for the `param_builder`, the following code could run in an initializers:

```ruby
Grape::Config.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`
Expand Down Expand Up @@ -618,6 +642,8 @@ params do
end
```

Or globally with the [Configuration](#configuration) `Grape::Config.param_builder`
myxoh marked this conversation as resolved.
Show resolved Hide resolved

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`.
Expand Down
1 change: 1 addition & 0 deletions lib/grape.rb
Expand Up @@ -34,6 +34,7 @@ module Grape
autoload :Namespace

autoload :Path
autoload :Config

autoload :Cookies
autoload :Validations
Expand Down
27 changes: 27 additions & 0 deletions lib/grape/config.rb
@@ -0,0 +1,27 @@
module Grape
module Config
module SettingStore
ATTRIBUTES = %i[
param_builder
].freeze

attr_accessor(*SettingStore::ATTRIBUTES)

def reset
self.param_builder = Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder
end

def configure
block_given? ? yield(self) : self
end

def config
self
end
end

Grape::Config.extend SettingStore
end
end

Grape::Config.reset
2 changes: 1 addition & 1 deletion lib/grape/request.rb
Expand Up @@ -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

Expand Down
19 changes: 19 additions & 0 deletions spec/grape/config_spec.rb
@@ -0,0 +1,19 @@
require 'spec_helper'

module Grape
describe Config do
let(:config_double) { Module.new { extend Config::SettingStore } }

context 'when configured' do
subject(:configure) do
config_double.configure do |config|
config.param_builder = 42
end
end

it 'changes the value' do
expect { configure }.to change { config_double.param_builder }.to(42)
end
end
end
end
18 changes: 18 additions & 0 deletions spec/grape/request_spec.rb
Expand Up @@ -62,6 +62,24 @@ module Grape
end
end

describe 'when the param_builder is set to Hashie' do
before do
myxoh marked this conversation as resolved.
Show resolved Hide resolved
allow(Grape::Config).to receive(:param_builder) { Grape::Extensions::Hashie::Mash::ParamBuilder }
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)
Expand Down