Skip to content

Commit

Permalink
Merge pull request #2378 from arg/fix_params_merging
Browse files Browse the repository at this point in the history
Do not overwrite route_param with a regular one if they share same name
  • Loading branch information
dblock authored Apr 1, 2024
2 parents a48754c + 8cdcf06 commit 5121279
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
* [#2387](https://github.com/ruby-grape/grape/pull/2387): Fix rubygems version within workflows - [@ericproulx](https://github.com/ericproulx).
* [#2405](https://github.com/ruby-grape/grape/pull/2405): Fix edge workflow - [@ericproulx](https://github.com/ericproulx).
* [#2414](https://github.com/ruby-grape/grape/pull/2414): Fix Rack::Lint missing content-type - [@ericproulx](https://github.com/ericproulx).
* [#2378](https://github.com/ruby-grape/grape/pull/2378): Do not overwrite `route_param` with a regular one if they share same name - [@arg](https://github.com/arg).
* Your contribution here.

### 2.0.0 (2023/11/11)
Expand Down
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
- [Include Parent Namespaces](#include-parent-namespaces)
- [Include Missing](#include-missing)
- [Evaluate Given](#evaluate-given)
- [Parameter Precedence](#parameter-precedence)
- [Parameter Validation and Coercion](#parameter-validation-and-coercion)
- [Supported Parameter Types](#supported-parameter-types)
- [Integer/Fixnum and Coercions](#integerfixnum-and-coercions)
Expand Down Expand Up @@ -1199,6 +1200,35 @@ curl -X POST -H "Content-Type: application/json" localhost:9292/child -d '{"chil
}
````

### Parameter Precedence

Using `route_param` takes higher precedence over a regular parameter defined with same name:

```ruby
params do
requires :foo, type: String
end
route_param :foo do
get do
{ value: params[:foo] }
end
end
```

**Request**

```bash
curl -X POST -H "Content-Type: application/json" localhost:9292/bar -d '{"foo": "baz"}'
```

**Response**

```json
{
"value": "bar"
}
```

## Parameter Validation and Coercion

You can define validations and coercion options for your parameters using a `params` block.
Expand Down
53 changes: 53 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,59 @@ The `rack_response` method has been deprecated and the `error_response` method h

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

#### Change in parameters precedence

When using together with `Grape::Extensions::Hash::ParamBuilder`, `route_param` takes higher precedence over a regular parameter defined with same name, which now matches the default param builder behavior.

This was a regression introduced by [#2326](https://github.com/ruby-grape/grape/pull/2326) in Grape v1.8.0.

```ruby
grape.configure do |config|
config.param_builder = Grape::Extensions::Hash::ParamBuilder
end

params do
requires :foo, type: String
end
route_param :foo do
get do
{ value: params[:foo] }
end
end
```

Request:

```bash
curl -X POST -H "Content-Type: application/json" localhost:9292/bar -d '{"foo": "baz"}'
```

Response prior to v1.8.0:

```json
{
"value": "bar"
}
```

v1.8.0..v2.0.0:

```json
{
"value": "baz"
}
```

v2.1.0+:

```json
{
"value": "bar"
}
```

See [#2378](https://github.com/ruby-grape/grape/pull/2378) for details.

#### Grape::Router::Route.route_xxx methods have been removed

- `route_method` is accessible through `request_method`
Expand Down
6 changes: 5 additions & 1 deletion lib/grape/extensions/hash.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@ module ParamBuilder

def build_params
rack_params.deep_dup.tap do |params|
params.deep_merge!(grape_routing_args) if env.key?(Grape::Env::GRAPE_ROUTING_ARGS)
params.deep_symbolize_keys!

if env.key?(Grape::Env::GRAPE_ROUTING_ARGS)
grape_routing_args.deep_symbolize_keys!
params.deep_merge!(grape_routing_args)
end
end
end
end
Expand Down
29 changes: 29 additions & 0 deletions spec/grape/extensions/param_builders/hash_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,34 @@ def app
expect(last_response.status).to eq(200)
expect(last_response.body).to eq('["bar", nil]')
end

it 'does not overwrite route_param with a regular param if they have same name' do
subject.namespace :route_param do
route_param :foo do
get { params.to_json }
end
end

get '/route_param/bar', foo: 'baz'
expect(last_response.status).to eq(200)
expect(last_response.body).to eq('{"foo":"bar"}')
end

it 'does not overwrite route_param with a defined regular param if they have same name' do
subject.namespace :route_param do
params do
requires :foo, type: String
end
route_param :foo do
get do
params[:foo]
end
end
end

get '/route_param/bar', foo: 'baz'
expect(last_response.status).to eq(200)
expect(last_response.body).to eq('bar')
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -101,5 +101,34 @@ def app
expect(last_response.body).to eq('["bar", "bar"]')
end
end

it 'does not overwrite route_param with a regular param if they have same name' do
subject.namespace :route_param do
route_param :foo do
get { params.to_json }
end
end

get '/route_param/bar', foo: 'baz'
expect(last_response.status).to eq(200)
expect(last_response.body).to eq('{"foo":"bar"}')
end

it 'does not overwrite route_param with a defined regular param if they have same name' do
subject.namespace :route_param do
params do
requires :foo, type: String
end
route_param :foo do
get do
[params[:foo], params['foo']]
end
end
end

get '/route_param/bar', foo: 'baz'
expect(last_response.status).to eq(200)
expect(last_response.body).to eq('["bar", "bar"]')
end
end
end
30 changes: 30 additions & 0 deletions spec/grape/extensions/param_builders/hashie/mash_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,5 +75,35 @@ def app
expect(last_response.status).to eq(200)
expect(last_response.body).to eq('["bar", "bar"]')
end

it 'does not overwrite route_param with a regular param if they have same name' do
subject.namespace :route_param do
route_param :foo do
get { params.to_json }
end
end

get '/route_param/bar', foo: 'baz'
expect(last_response.status).to eq(200)
expect(last_response.body).to eq('{"foo":"bar"}')
end

it 'does not overwrite route_param with a defined regular param if they have same name' do
subject.namespace :route_param do
params do
build_with Grape::Extensions::Hashie::Mash::ParamBuilder # rubocop:disable RSpec/DescribedClass
requires :foo, type: String
end
route_param :foo do
get do
[params[:foo], params['foo']]
end
end
end

get '/route_param/bar', foo: 'baz'
expect(last_response.status).to eq(200)
expect(last_response.body).to eq('["bar", "bar"]')
end
end
end

0 comments on commit 5121279

Please sign in to comment.