Skip to content

Commit

Permalink
Merge pull request #1610 from dblock/hash-with-indifferent-access
Browse files Browse the repository at this point in the history
Replace Hashie::Mash with ActiveSupport::HashWithIndifferentAccess.
  • Loading branch information
dblock authored Apr 14, 2017
2 parents ee62ea5 + d931da3 commit 91c6c78
Show file tree
Hide file tree
Showing 33 changed files with 771 additions and 94 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,11 @@ coverage
doc
pkg
.rvmrc
.ruby-version
.ruby-gemset
.bundle
.yardoc/*
.byebug_history
dist
Gemfile.lock
gemfiles/*.lock
Expand Down
44 changes: 22 additions & 22 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#### Features

* [#1594](https://github.com/ruby-grape/grape/pull/1594): Replace `Hashie::Mash` parameters with `ActiveSupport::HashWithIndifferentAccess` - [@james2m](https://github.com/james2m), [@dblock](https://github.com/dblock).
* Your contribution here.

#### Fixes
Expand Down Expand Up @@ -34,58 +35,57 @@

#### Features

* [#1536](https://github.com/ruby-grape/grape/pull/1536): Updates `invalid_versioner_option` translation - [@Lavode](https://github.com/Lavode).
* [#1543](https://github.com/ruby-grape/grape/pull/1543): Support ruby 2.4 - [@LeFnord](https://github.com/LeFnord), [@namusyaka](https://github.com/namusyaka).
* [#1536](https://github.com/ruby-grape/grape/pull/1536): Updated `invalid_versioner_option` translation - [@Lavode](https://github.com/Lavode).
* [#1543](https://github.com/ruby-grape/grape/pull/1543): Added support for ruby 2.4 - [@LeFnord](https://github.com/LeFnord), [@namusyaka](https://github.com/namusyaka).

#### Fixes

* [#1548](https://github.com/ruby-grape/grape/pull/1548): Avoid failing even if given path does not match with prefix - [@thomas-peyric](https://github.com/thomas-peyric), [@namusyaka](https://github.com/namusyaka).
* [#1550](https://github.com/ruby-grape/grape/pull/1550): Use 200 as default status for deletes that reply with content - [@jthornec](https://github.com/jthornec).
* [#1548](https://github.com/ruby-grape/grape/pull/1548): Fix: avoid failing even if given path does not match with prefix - [@thomas-peyric](https://github.com/thomas-peyric), [@namusyaka](https://github.com/namusyaka).
* [#1550](https://github.com/ruby-grape/grape/pull/1550): Fix: return 200 as default status for DELETE - [@jthornec](https://github.com/jthornec).

### 0.19.0 (12/18/2016)

#### Features

* [#1503](https://github.com/ruby-grape/grape/pull/1503): Allow to use regexp validator with arrays - [@akoltun](https://github.com/akoltun).
* [#1507](https://github.com/ruby-grape/grape/pull/1507): Add group attributes for parameter definitions - [@304](https://github.com/304).
* [#1532](https://github.com/ruby-grape/grape/pull/1532): Sets 204 as default status for delete - [@LeFnord](https://github.com/LeFnord).
* [#1503](https://github.com/ruby-grape/grape/pull/1503): Allowed use of regexp validator with arrays - [@akoltun](https://github.com/akoltun).
* [#1507](https://github.com/ruby-grape/grape/pull/1507): Added group attributes for parameter definitions - [@304](https://github.com/304).
* [#1532](https://github.com/ruby-grape/grape/pull/1532): Set 204 as default status for DELETE - [@LeFnord](https://github.com/LeFnord).

#### Fixes

* [#1505](https://github.com/ruby-grape/grape/pull/1505): Run `before` and `after` callbacks, but skip the rest when handling OPTIONS - [@jlfaber](https://github.com/jlfaber).
* [#1517](https://github.com/ruby-grape/grape/pull/1517), [#1089](https://github.com/ruby-grape/grape/pull/1089): Fix: priority of ANY routes - [@namusyaka](https://github.com/namusyaka), [@wagenet](https://github.com/wagenet).
* [#1512](https://github.com/ruby-grape/grape/pull/1512): Fix: deeply nested parameters are included within `#declared(params)` - [@krbs](https://github.com/krbs).
* [#1510](https://github.com/ruby-grape/grape/pull/1510): Fix: inconsistent validation for multiple parameters - [@dgasper](https://github.com/dgasper).
* [#1526](https://github.com/ruby-grape/grape/pull/1526): Reduce warnings caused by instance variables not initialized - [@cpetschnig](https://github.com/cpetschnig).
* [#1531](https://github.com/ruby-grape/grape/pull/1531): Updates gem dependencies - [@LeFnord](https://github.com/LeFnord).
* [#1526](https://github.com/ruby-grape/grape/pull/1526): Reduced warnings caused by instance variables not initialized - [@cpetschnig](https://github.com/cpetschnig).

### 0.18.0 (10/7/2016)

#### Features

* [#1480](https://github.com/ruby-grape/grape/pull/1480): Use the ruby-grape-danger gem for PR linting - [@dblock](https://github.com/dblock).
* [#1480](https://github.com/ruby-grape/grape/pull/1480): Used the ruby-grape-danger gem for PR linting - [@dblock](https://github.com/dblock).
* [#1486](https://github.com/ruby-grape/grape/pull/1486): Implemented except in values validator - [@jonmchan](https://github.com/jonmchan).
* [#1470](https://github.com/ruby-grape/grape/pull/1470): Drop support for ruby-2.0 - [@namusyaka](https://github.com/namusyaka).
* [#1490](https://github.com/ruby-grape/grape/pull/1490): Switch to Ruby-2.x+ syntax - [@namusyaka](https://github.com/namusyaka).
* [#1499](https://github.com/ruby-grape/grape/pull/1499): Support fail_fast param validation option - [@dgasper](https://github.com/dgasper).
* [#1470](https://github.com/ruby-grape/grape/pull/1470): Dropped support for Ruby 2.0 - [@namusyaka](https://github.com/namusyaka).
* [#1490](https://github.com/ruby-grape/grape/pull/1490): Switched to Ruby-2.x+ syntax - [@namusyaka](https://github.com/namusyaka).
* [#1499](https://github.com/ruby-grape/grape/pull/1499): Support `fail_fast` param validation option - [@dgasper](https://github.com/dgasper).

#### Fixes

* [#1498](https://github.com/ruby-grape/grape/pull/1498): Skip validations in inactive given blocks - [@jlfaber](https://github.com/jlfaber).
* [#1479](https://github.com/ruby-grape/grape/pull/1479): Support inserting middleware before/after anonymous classes in the middleware stack - [@rosa](https://github.com/rosa).
* [#1488](https://github.com/ruby-grape/grape/pull/1488): Ensure calling before filters when receiving OPTIONS request - [@namusyaka](https://github.com/namusyaka), [@jlfaber](https://github.com/jlfaber).
* [#1493](https://github.com/ruby-grape/grape/pull/1493): Coercion and lambda fails params validation - [@jonmchan](https://github.com/jonmchan).
* [#1498](https://github.com/ruby-grape/grape/pull/1498): Fix: skip validations in inactive given blocks - [@jlfaber](https://github.com/jlfaber).
* [#1479](https://github.com/ruby-grape/grape/pull/1479): Fix: support inserting middleware before/after anonymous classes in the middleware stack - [@rosa](https://github.com/rosa).
* [#1488](https://github.com/ruby-grape/grape/pull/1488): Fix: ensure calling before filters when receiving OPTIONS request - [@namusyaka](https://github.com/namusyaka), [@jlfaber](https://github.com/jlfaber).
* [#1493](https://github.com/ruby-grape/grape/pull/1493): Fix: coercion and lambda fails params validation - [@jonmchan](https://github.com/jonmchan).

### 0.17.0 (7/29/2016)

#### Features

* [#1393](https://github.com/ruby-grape/grape/pull/1393): Middleware can be inserted before or after default Grape middleware - [@ridiculous](https://github.com/ridiculous).
* [#1390](https://github.com/ruby-grape/grape/pull/1390): Allow inserting middleware at arbitrary points in the middleware stack - [@rosa](https://github.com/rosa).
* [#1366](https://github.com/ruby-grape/grape/pull/1366): Store `message_key` on `Grape::Exceptions::Validation` - [@mkou](https://github.com/mkou).
* [#1398](https://github.com/ruby-grape/grape/pull/1398): Add `rescue_from :grape_exceptions` - allow Grape to use the built-in `Grape::Exception` handing and use `rescue :all` behavior for everything else - [@mmclead](https://github.com/mmclead).
* [#1443](https://github.com/ruby-grape/grape/pull/1443): Extend `given` to receive a `Proc` - [@glaucocustodio](https://github.com/glaucocustodio).
* [#1455](https://github.com/ruby-grape/grape/pull/1455): Add an automated PR linter - [@orta](https://github.com/orta).
* [#1390](https://github.com/ruby-grape/grape/pull/1390): Allowed inserting middleware at arbitrary points in the middleware stack - [@rosa](https://github.com/rosa).
* [#1366](https://github.com/ruby-grape/grape/pull/1366): Stored `message_key` on `Grape::Exceptions::Validation` - [@mkou](https://github.com/mkou).
* [#1398](https://github.com/ruby-grape/grape/pull/1398): Added `rescue_from :grape_exceptions` - allow Grape to use the built-in `Grape::Exception` handing and use `rescue :all` behavior for everything else - [@mmclead](https://github.com/mmclead).
* [#1443](https://github.com/ruby-grape/grape/pull/1443): Extended `given` to receive a `Proc` - [@glaucocustodio](https://github.com/glaucocustodio).
* [#1455](https://github.com/ruby-grape/grape/pull/1455): Added an automated PR linter - [@orta](https://github.com/orta).

#### Fixes

Expand Down
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ group :development, :test do
gem 'bundler'
gem 'rake'
gem 'rubocop', '0.47.0'
gem 'hashie'
end

group :development do
Expand Down
60 changes: 41 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
- [Param](#param)
- [Describing Methods](#describing-methods)
- [Parameters](#parameters)
- [Params Class](#params-class)
- [Declared](#declared)
- [Include Missing](#include-missing)
- [Parameter Validation and Coercion](#parameter-validation-and-coercion)
Expand Down Expand Up @@ -495,7 +496,36 @@ In the case of conflict between either of:
* `GET`, `POST` and `PUT` parameters
* the contents of the request body on `POST` and `PUT`

route string parameters will have precedence.
Route string parameters will have precedence.

### Params Class

By default parameters are available as `ActiveSupport::HashWithIndifferentAccess`. This can be changed to, for example, Ruby `Hash` or `Hashie::Mash` for the entire API.

```ruby
class API < Grape::API
include Grape::Extensions::Hashie::Mash::ParamBuilder

params do
optional :color, type: String
end
get do
params.color # instead of params[:color]
end
```

The class can also be overridden on individual parameter blocks using `build_with` as follows.

```ruby
params do
build_with Grape::Extensions::Hash::ParamBuilder
optional :color, type: String
end
```

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`.

### Declared

Expand All @@ -509,7 +539,7 @@ post 'users/signup' do
end
````

If we do not specify any params, `declared` will return an empty `Hashie::Mash` instance.
If you do not specify any parameters, `declared` will return an empty hash.

**Request**

Expand All @@ -526,7 +556,7 @@ curl -X POST -H "Content-Type: application/json" localhost:9292/users/signup -d

````

Once we add parameters requirements, grape will start returning only the declared params.
Once we add parameters requirements, grape will start returning only the declared parameters.

````ruby
format :json
Expand Down Expand Up @@ -562,17 +592,11 @@ curl -X POST -H "Content-Type: application/json" localhost:9292/users/signup -d
}
````

The returned hash is a `Hashie::Mash` instance, allowing you to access parameters via dot notation:

```ruby
declared(params).user == declared(params)['user']
```

The returned hash is an `ActiveSupport::HashWithIndifferentAccess`.

The `#declared` method is not available to `before` filters, as those are evaluated prior
to parameter coercion.
The `#declared` method is not available to `before` filters, as those are evaluated prior to parameter coercion.

### Include parent namespaces
### Include Parent Namespaces

By default `declared(params)` includes parameters that were defined in all parent namespaces. If you want to return only parameters from your current namespace, you can set `include_parent_namespaces` option to `false`.

Expand Down Expand Up @@ -897,18 +921,16 @@ end

### Multipart File Parameters

Grape makes use of `Rack::Request`'s built-in support for multipart
file parameters. Such parameters can be declared with `type: File`:
Grape makes use of `Rack::Request`'s built-in support for multipart file parameters. Such parameters can be declared with `type: File`:

```ruby
params do
requires :avatar, type: File
end
post '/' do
# Parameter will be wrapped using Hashie:
params.avatar.filename # => 'avatar.png'
params.avatar.type # => 'image/png'
params.avatar.tempfile # => #<File>
params[:avatar][:filename] # => 'avatar.png'
params[:avatar][:avatar] # => 'image/png'
params[:avatar][:tempfile] # => #<File>
end
```

Expand Down Expand Up @@ -1381,7 +1403,7 @@ class Admin < Grape::Validations::Base
# @attrs is a list containing the attribute we are currently validating
# in our sample case this method once will get called with
# @attrs being [:admin_field] and once with @attrs being [:admin_false_field]
return unless request.params.key? @attrs.first
return unless request.params.key?(@attrs.first)
# check if admin flag is set to true
return unless @option
# check if user is admin or not
Expand Down
51 changes: 51 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,57 @@
Upgrading Grape
===============

### Upgrading to >= 1.0.0

#### Changes in Parameter Class

The default class for `params` has changed from `Hashie::Mash` to `ActiveSupport::HashWithIndifferentAccess` and the `hashie` dependency has been removed. This means that by default you can no longer access parameters by method name.

```
class API < Grape::API
params do
optional :color, type: String
end
get do
params[:color] # use params[:color] instead of params.color
end
end
```

To restore the behavior of prior versions, add `hashie` to your `Gemfile` and `include Grape::Extensions::Hashie::Mash::ParamBuilder` in your API.

```
class API < Grape::API
include Grape::Extensions::Hashie::Mash::ParamBuilder
params do
optional :color, type: String
end
get do
# params.color works
end
end
```

This behavior can also be overridden on individual parameter blocks using `build_with`.

```ruby
params do
build_with Grape::Extensions::Hash::ParamBuilder
optional :color, type: String
end
```

If you're constructing your own `Grape::Request` in a middleware, you can pass different parameter handlers to create the desired `params` class with `build_params_with`.

```ruby
def request
Grape::Request.new(env, build_params_with: Grape::Extensions::Hashie::Mash::ParamBuilder)
end
```

See [#1610](https://github.com/ruby-grape/grape/pull/1610) for more information.

### Upgrading to >= 0.19.1

#### DELETE now defaults to status code 200 for responses with a body, or 204 otherwise
Expand Down
1 change: 1 addition & 0 deletions gemfiles/rack_1.5.2.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ group :development, :test do
gem 'bundler'
gem 'rake'
gem 'rubocop', '0.47.0'
gem 'hashie'
end

group :development do
Expand Down
1 change: 1 addition & 0 deletions gemfiles/rack_edge.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ group :development, :test do
gem 'bundler'
gem 'rake'
gem 'rubocop', '0.47.0'
gem 'hashie'
end

group :development do
Expand Down
1 change: 1 addition & 0 deletions gemfiles/rails_3.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ group :development, :test do
gem 'bundler'
gem 'rake'
gem 'rubocop', '0.47.0'
gem 'hashie'
end

group :development do
Expand Down
1 change: 1 addition & 0 deletions gemfiles/rails_4.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ group :development, :test do
gem 'bundler'
gem 'rake'
gem 'rubocop', '0.47.0'
gem 'hashie'
end

group :development do
Expand Down
1 change: 1 addition & 0 deletions gemfiles/rails_5.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ group :development, :test do
gem 'bundler'
gem 'rake'
gem 'rubocop', '0.47.0'
gem 'hashie'
end

group :development do
Expand Down
1 change: 1 addition & 0 deletions gemfiles/rails_edge.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ group :development, :test do
gem 'bundler'
gem 'rake'
gem 'rubocop', '0.47.0'
gem 'hashie'
end

group :development do
Expand Down
1 change: 0 additions & 1 deletion grape.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ Gem::Specification.new do |s|
s.add_runtime_dependency 'activesupport'
s.add_runtime_dependency 'multi_json', '>= 1.3.2'
s.add_runtime_dependency 'multi_xml', '>= 0.5.2'
s.add_runtime_dependency 'hashie', '>= 2.1.0'
s.add_runtime_dependency 'virtus', '>= 1.0.0'
s.add_runtime_dependency 'builder'

Expand Down
Loading

0 comments on commit 91c6c78

Please sign in to comment.