Skip to content

Commit 7d1b3e3

Browse files
304dblock
authored andcommitted
Fix include_parent_namespaces.
1 parent 4d1883f commit 7d1b3e3

File tree

4 files changed

+103
-33
lines changed

4 files changed

+103
-33
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
* [#1380](https://github.com/ruby-grape/grape/pull/1380): Fix `allow_blank: false` for `Time` attributes with valid values causes `NoMethodError` - [@ipkes](https://github.com/ipkes).
1717
* [#1384](https://github.com/ruby-grape/grape/pull/1384): Fix parameter validation with an empty optional nested `Array` - [@ipkes](https://github.com/ipkes).
1818
* [#1414](https://github.com/ruby-grape/grape/pull/1414): Fix multiple version definitions for path versioning - [@304](https://github.com/304).
19+
* [#1415](https://github.com/ruby-grape/grape/pull/1415): Fix `declared(params, include_parent_namespaces: false)` - [@304](https://github.com/304).
1920

2021
0.16.2 (4/12/2016)
2122
==================

README.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,52 @@ The returned hash is a `Hashie::Mash` instance, allowing you to access parameter
554554
The `#declared` method is not available to `before` filters, as those are evaluated prior
555555
to parameter coercion.
556556

557+
### Include parent namespaces
558+
559+
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`.
560+
561+
````ruby
562+
format :json
563+
564+
namespace :parent do
565+
params do
566+
requires :parent_name, type: String
567+
end
568+
569+
namespace ':parent_name' do
570+
params do
571+
requires :child_name, type: String
572+
end
573+
get ':child_name' do
574+
{
575+
'without_parent_namespaces' => declared(params, include_parent_namespaces: false),
576+
'with_parent_namespaces' => declared(params, include_parent_namespaces: true),
577+
}
578+
end
579+
end
580+
end
581+
````
582+
583+
**Request**
584+
585+
````bash
586+
curl -X GET -H "Content-Type: application/json" localhost:9292/parent/foo/bar
587+
````
588+
589+
**Response**
590+
591+
````json
592+
{
593+
"without_parent_namespaces": {
594+
"child_name": "bar"
595+
},
596+
"with_parent_namespaces": {
597+
"parent_name": "foo",
598+
"child_name": "bar"
599+
},
600+
}
601+
````
602+
557603
### Include missing
558604

559605
By default `declared(params)` includes parameters that have `nil` values. If you want to return only the parameters that are not `nil`, you can use the `include_missing` option. By default, `include_missing` is set to `true`. Consider the following API:

lib/grape/dsl/inside_route.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ module PostBeforeFilter
2929
def declared(params, options = {}, declared_params = nil)
3030
options = options.reverse_merge(include_missing: true, include_parent_namespaces: true)
3131

32-
declared_params ||= (!options[:include_parent_namespaces] ? route_setting(:declared_params) : (route_setting(:saved_declared_params) || [])).flatten(1) || []
32+
all_declared_params = route_setting(:declared_params)
33+
current_namespace_declared_params = route_setting(:saved_declared_params).last
34+
35+
declared_params ||= options[:include_parent_namespaces] ? all_declared_params : current_namespace_declared_params
3336

3437
raise ArgumentError, 'Tried to filter for declared parameters but none exist.' unless declared_params
3538

spec/grape/endpoint_spec.rb

Lines changed: 52 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -466,49 +466,69 @@ def app
466466
describe '#declared; call from child namespace' do
467467
before do
468468
subject.format :json
469-
subject.namespace :something do
469+
subject.namespace :parent do
470470
params do
471-
requires :id, type: Integer
471+
requires :parent_name, type: String
472472
end
473-
resource ':id' do
474-
params do
475-
requires :foo
476-
optional :bar
477-
end
478-
get do
479-
{
480-
params: params,
481-
declared_params: declared(params)
482-
}
483-
end
473+
474+
namespace ':parent_name' do
484475
params do
485-
requires :happy
486-
optional :days
476+
requires :child_name, type: String
477+
requires :child_age, type: Integer
487478
end
488-
get '/test' do
489-
{
490-
params: params,
491-
declared_params: declared(params, include_parent_namespaces: false)
492-
}
479+
480+
namespace ':child_name' do
481+
params do
482+
requires :grandchild_name, type: String
483+
end
484+
485+
get ':grandchild_name' do
486+
{
487+
'params' => params,
488+
'without_parent_namespaces' => declared(params, include_parent_namespaces: false),
489+
'with_parent_namespaces' => declared(params, include_parent_namespaces: true)
490+
}
491+
end
493492
end
494493
end
495494
end
495+
496+
get '/parent/foo/bar/baz', child_age: 5, extra: 'hello'
496497
end
497498

498-
it 'should include params defined in the parent namespace' do
499-
get '/something/123', foo: 'test', extra: 'hello'
500-
expect(last_response.status).to eq 200
501-
json = JSON.parse(last_response.body, symbolize_names: true)
502-
expect(json[:params][:id]).to eq 123
503-
expect(json[:declared_params].keys).to match_array [:foo, :bar, :id]
499+
let(:parsed_response) { JSON.parse(last_response.body, symbolize_names: true) }
500+
501+
it { expect(last_response.status).to eq 200 }
502+
503+
context 'with include_parent_namespaces: false' do
504+
it 'returns declared parameters only from current namespace' do
505+
expect(parsed_response[:without_parent_namespaces]).to eq(
506+
grandchild_name: 'baz'
507+
)
508+
end
504509
end
505510

506-
it 'does not include params defined in the parent namespace with include_parent_namespaces: false' do
507-
get '/something/123/test', happy: 'test', extra: 'hello'
508-
expect(last_response.status).to eq 200
509-
json = JSON.parse(last_response.body, symbolize_names: true)
510-
expect(json[:params][:id]).to eq 123
511-
expect(json[:declared_params].keys).to match_array [:happy, :days]
511+
context 'with include_parent_namespaces: true' do
512+
it 'returns declared parameters from every parent namespace' do
513+
expect(parsed_response[:with_parent_namespaces]).to eq(
514+
parent_name: 'foo',
515+
child_name: 'bar',
516+
grandchild_name: 'baz',
517+
child_age: 5
518+
)
519+
end
520+
end
521+
522+
context 'without declaration' do
523+
it 'returns all requested parameters' do
524+
expect(parsed_response[:params]).to eq(
525+
parent_name: 'foo',
526+
child_name: 'bar',
527+
grandchild_name: 'baz',
528+
child_age: 5,
529+
extra: 'hello'
530+
)
531+
end
512532
end
513533
end
514534

0 commit comments

Comments
 (0)