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

Do not overwrite route_param with a regular one if they share same name #2378

Merged
merged 1 commit into from
Apr 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,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 @@ -1198,6 +1199,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
dblock marked this conversation as resolved.
Show resolved Hide resolved
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
Loading