diff --git a/CHANGELOG.md b/CHANGELOG.md index d1a554be59..21ac889533 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * [#2176](https://github.com/ruby-grape/grape/pull/2176): Fix: OPTIONS fails if matching all routes - [@myxoh](https://github.com/myxoh). * [#2177](https://github.com/ruby-grape/grape/pull/2177): Fix: `default` validator fails if preceded by `as` validator - [@Catsuko](https://github.com/Catsuko). +* [#2180](https://github.com/ruby-grape/grape/pull/2180): Call `super` in `API.inherited` - [@yogeshjain999](https://github.com/yogeshjain999). * Your contribution here. ### 1.5.3 (2021/03/07) diff --git a/lib/grape/api.rb b/lib/grape/api.rb index 11bcb6a447..9d81bf95b7 100644 --- a/lib/grape/api.rb +++ b/lib/grape/api.rb @@ -20,10 +20,11 @@ def new(*args, &block) # When inherited, will create a list of all instances (times the API was mounted) # It will listen to the setup required to mount that endpoint, and replicate it on any new instance - def inherited(api, base_instance_parent = Grape::API::Instance) - api.initial_setup(base_instance_parent) + def inherited(api) + super + + api.initial_setup(Grape::API == self ? Grape::API::Instance : @base_instance) api.override_all_methods! - make_inheritable(api) end # Initialize the instance variables on the remountable class, and the base_instance @@ -68,15 +69,6 @@ def call(*args, &block) instance_for_rack.call(*args, &block) end - # Allows an API to itself be inheritable: - def make_inheritable(api) - # When a child API inherits from a parent API. - def api.inherited(child_api) - # The instances of the child API inherit from the instances of the parent API - Grape::API.inherited(child_api, base_instance) - end - end - # Alleviates problems with autoloading by tring to search for the constant def const_missing(*args) if base_instance.const_defined?(*args) diff --git a/spec/grape/api_spec.rb b/spec/grape/api_spec.rb index 126b816f2a..af2419ceb7 100644 --- a/spec/grape/api_spec.rb +++ b/spec/grape/api_spec.rb @@ -4081,6 +4081,49 @@ def before end end + describe '.inherited' do + context 'overriding within class' do + let(:root_api) do + Class.new(Grape::API) do + @bar = 'Hello, world' + + def self.inherited(child_api) + super + child_api.instance_variable_set(:@foo, @bar.dup) + end + end + end + + let(:child_api) { Class.new(root_api) } + + it 'allows overriding the hook' do + expect(child_api.instance_variable_get(:@foo)).to eq('Hello, world') + end + end + + context 'overriding via composition' do + module Inherited + def inherited(api) + super + api.instance_variable_set(:@foo, @bar.dup) + end + end + + let(:root_api) do + Class.new(Grape::API) do + @bar = 'Hello, world' + extend Inherited + end + end + + let(:child_api) { Class.new(root_api) } + + it 'allows overriding the hook' do + expect(child_api.instance_variable_get(:@foo)).to eq('Hello, world') + end + end + end + describe 'const_missing' do subject(:grape_api) { Class.new(Grape::API) } let(:mounted) do