diff --git a/lib/jsonapi/link_builder.rb b/lib/jsonapi/link_builder.rb index c49633d7f..13200cb44 100644 --- a/lib/jsonapi/link_builder.rb +++ b/lib/jsonapi/link_builder.rb @@ -115,7 +115,7 @@ def formatted_module_path_from_class(klass) scopes = module_scopes_from_class(klass) unless scopes.empty? - "/#{ scopes.map{ |scope| format_route(scope.to_s.underscore) }.join('/') }/" + "/#{ scopes.map{ |scope| format_route(scope.to_s.underscore) }.compact.join('/') }/" else "/" end diff --git a/test/fixtures/active_record.rb b/test/fixtures/active_record.rb index ce3fa0323..bb204cd20 100644 --- a/test/fixtures/active_record.rb +++ b/test/fixtures/active_record.rb @@ -1929,6 +1929,13 @@ class PersonResource < JSONAPI::Resource end end +module OptionalNamespace + module V1 + class PersonResource < JSONAPI::Resource + end + end +end + module MyEngine module Api module V1 @@ -1950,6 +1957,13 @@ class PersonResource < JSONAPI::Resource end end end + + module OptionalNamespace + module V1 + class PersonResource < JSONAPI::Resource + end + end + end end module ApiV2Engine diff --git a/test/test_helper.rb b/test/test_helper.rb index 5d79ef2e6..15d4570b7 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -421,6 +421,12 @@ class CatResource < JSONAPI::Resource jsonapi_resources :people end end + + namespace :optional_namespace, path: 'optional_namespace' do + namespace :v1, path: '' do + jsonapi_resources :people + end + end end ApiV2Engine::Engine.routes.draw do @@ -670,3 +676,16 @@ def unformat(value) end end end + +class OptionalRouteFormatter < JSONAPI::RouteFormatter + class << self + def format(route) + return if route == 'v1' + super + end + + def unformat(formatted_route) + super + end + end +end diff --git a/test/unit/serializer/link_builder_test.rb b/test/unit/serializer/link_builder_test.rb index a91238a7b..3dcd5774f 100644 --- a/test/unit/serializer/link_builder_test.rb +++ b/test/unit/serializer/link_builder_test.rb @@ -302,6 +302,20 @@ def test_query_link_for_regular_app_with_dasherized_scope assert_equal expected_link, builder.query_link(query) end + def test_query_link_for_regular_app_with_optional_scope + config = { + base_url: @base_url, + route_formatter: OptionalRouteFormatter, + primary_resource_klass: OptionalNamespace::V1::PersonResource + } + + query = { page: { offset: 0, limit: 12 } } + builder = JSONAPI::LinkBuilder.new(config) + expected_link = "#{ @base_url }/optional_namespace/people?page%5Blimit%5D=12&page%5Boffset%5D=0" + + assert_equal expected_link, builder.query_link(query) + end + def test_query_link_for_engine config = { base_url: @base_url, @@ -344,6 +358,20 @@ def test_query_link_for_engine_with_dasherized_scope assert_equal expected_link, builder.query_link(query) end + def test_query_link_for_engine_with_optional_scope + config = { + base_url: @base_url, + route_formatter: OptionalRouteFormatter, + primary_resource_klass: MyEngine::OptionalNamespace::V1::PersonResource + } + + query = { page: { offset: 0, limit: 12 } } + builder = JSONAPI::LinkBuilder.new(config) + expected_link = "#{ @base_url }/boomshaka/optional_namespace/people?page%5Blimit%5D=12&page%5Boffset%5D=0" + + assert_equal expected_link, builder.query_link(query) + end + def test_query_link_for_engine_with_camel_case_scope config = { base_url: @base_url,