belt 0.3.40 → 0.3.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 848174ed726800ea7e2a60b16a43714e558bf8adae32017a195a4ef0982cff11
4
- data.tar.gz: 3d71874ef9d72422b72059e768de032b07caeb9b719bfaaf307d5d4d634b48ee
3
+ metadata.gz: 1a7141bc9a4eff54bdc3b4c010d47f08c3917aed5072dfa2f976f83429c7c00e
4
+ data.tar.gz: 367789f59346408d662c87a955d22f95b7405d90f9711e819e216c58c155db17
5
5
  SHA512:
6
- metadata.gz: f431f7d645a3e94cdbf799f0d6fdd44a817491fd991da85b3bce7df95e760359638b1eeb528b39f3dc33edc51a324f4d0a4627152e0e4c025749020b3549ab91
7
- data.tar.gz: 59fc7c275194d8ac49c4f69a0eb0109dcdf516eb1f6f597d5c7a9a5f0e16046d2d0dd6c88920c94c58735e643a0e231b3ce331fa919a7bc1d240c91ecb710c2f
6
+ metadata.gz: a5c9427efe1511e4f429ff46a7f14043a17b06c490915f62c535471ac984abcccda54801f765bf24e2b39e8a8f83b8939af53c69ad1414ae677cdf15d1943dd8
7
+ data.tar.gz: 4e90da0c8d2391bd3f7170acffeb083d04c3585092df86f413d4f3d2663386c21bac8ca6e833aecdea6883882569360d3b02e4239a17f52cf457fe65ed31b5d0
data/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.41
4
+
5
+ ### Bug Fix
6
+
7
+ - **Fix API Gateway sibling path parameter conflict**: When a resource has nested
8
+ resources (a block), member routes (show, update, destroy) now use `{param_name}`
9
+ (e.g., `{project_id}`) instead of `{id}` to match the nested routes. This prevents
10
+ API Gateway from rejecting routes due to sibling path segments having different
11
+ parameter names.
12
+
13
+ Without nested resources (no block):
14
+ ```
15
+ GET /posts/{id}
16
+ PUT /posts/{id}
17
+ DELETE /posts/{id}
18
+ ```
19
+
20
+ With nested resources:
21
+ ```
22
+ GET /projects/{project_id}
23
+ PUT /projects/{project_id}
24
+ DELETE /projects/{project_id}
25
+ GET /projects/{project_id}/epics
26
+ GET /projects/{project_id}/epics/{id}
27
+ ```
28
+
29
+ This fixes the error: "Unable to create resource at path '...': A sibling ({id})
30
+ of this resource already has a variable path part".
31
+
3
32
  ## 0.3.40
4
33
 
5
34
  ### Breaking Change
@@ -416,9 +416,12 @@ module Belt
416
416
  resource_options = options.merge(route_type: :resources)
417
417
  actions = determine_actions(options)
418
418
 
419
- add_resource_routes(resource_name, param_name, resource_options, actions)
419
+ # When there are nested resources, use {param_name} for member routes to avoid
420
+ # API Gateway sibling path parameter conflicts. Without nested resources, use {id}.
421
+ has_nested = block_given?
422
+ add_resource_routes(resource_name, param_name, resource_options, actions, use_param_name: has_nested)
420
423
 
421
- return unless block_given?
424
+ return unless has_nested
422
425
 
423
426
  collection_prefix = "/#{resource_name}"
424
427
  member_prefix = "/#{resource_name}/{#{param_name}}"
@@ -497,8 +500,11 @@ module Belt
497
500
  options.merge(tables: [resource_name.to_sym])
498
501
  end
499
502
 
500
- def add_resource_routes(resource_name, _param_name, resource_options, actions)
501
- # Member routes (show/update/destroy) use {id}, not {singular_id} Rails convention
503
+ def add_resource_routes(resource_name, param_name, resource_options, actions, use_param_name: false)
504
+ # Member routes (show/update/destroy) use {id} by default (Rails convention).
505
+ # When nested resources exist (use_param_name: true), use {param_name} instead
506
+ # to avoid API Gateway sibling path parameter conflicts.
507
+ member_param = use_param_name ? param_name : 'id'
502
508
  if actions.include?(:index)
503
509
  add_route(:get, "/#{resource_name}",
504
510
  resolve_request_model_for(resource_options, :index))
@@ -508,16 +514,16 @@ module Belt
508
514
  resolve_request_model_for(resource_options, :create))
509
515
  end
510
516
  if actions.include?(:show)
511
- add_route(:get, "/#{resource_name}/{id}",
517
+ add_route(:get, "/#{resource_name}/{#{member_param}}",
512
518
  resolve_request_model_for(resource_options, :show))
513
519
  end
514
520
  if actions.include?(:update)
515
- add_route(:put, "/#{resource_name}/{id}",
521
+ add_route(:put, "/#{resource_name}/{#{member_param}}",
516
522
  resolve_request_model_for(resource_options, :update))
517
523
  end
518
524
  return unless actions.include?(:destroy)
519
525
 
520
- add_route(:delete, "/#{resource_name}/{id}", resolve_request_model_for(resource_options, :destroy))
526
+ add_route(:delete, "/#{resource_name}/{#{member_param}}", resolve_request_model_for(resource_options, :destroy))
521
527
  end
522
528
 
523
529
  def resolve_request_model_for(options, action)
@@ -799,8 +805,11 @@ module Belt
799
805
  end
800
806
  end
801
807
 
802
- def add_scoped_resource_routes(resource_name, _param_name, resource_options, actions)
803
- # Member routes (show/update/destroy) use {id}, not {singular_id} Rails convention
808
+ def add_scoped_resource_routes(resource_name, param_name, resource_options, actions, use_param_name: false)
809
+ # Member routes (show/update/destroy) use {id} by default (Rails convention).
810
+ # When nested resources exist (use_param_name: true), use {param_name} instead
811
+ # to avoid API Gateway sibling path parameter conflicts.
812
+ member_param = use_param_name ? param_name : 'id'
804
813
  if actions.include?(:index)
805
814
  @gateway.send(:add_route, :get, build_path("/#{resource_name}"),
806
815
  resolve_request_model_for(resource_options, :index))
@@ -810,16 +819,16 @@ module Belt
810
819
  resolve_request_model_for(resource_options, :create))
811
820
  end
812
821
  if actions.include?(:show)
813
- @gateway.send(:add_route, :get, build_path("/#{resource_name}/{id}"),
822
+ @gateway.send(:add_route, :get, build_path("/#{resource_name}/{#{member_param}}"),
814
823
  resolve_request_model_for(resource_options, :show))
815
824
  end
816
825
  if actions.include?(:update)
817
- @gateway.send(:add_route, :put, build_path("/#{resource_name}/{id}"),
826
+ @gateway.send(:add_route, :put, build_path("/#{resource_name}/{#{member_param}}"),
818
827
  resolve_request_model_for(resource_options, :update))
819
828
  end
820
829
  return unless actions.include?(:destroy)
821
830
 
822
- @gateway.send(:add_route, :delete, build_path("/#{resource_name}/{id}"),
831
+ @gateway.send(:add_route, :delete, build_path("/#{resource_name}/{#{member_param}}"),
823
832
  resolve_request_model_for(resource_options, :destroy))
824
833
  end
825
834
 
@@ -842,7 +851,10 @@ module Belt
842
851
  resource_options = options.merge(route_type: :resources, controller: controller)
843
852
  actions = determine_scoped_actions(options)
844
853
 
845
- add_scoped_resource_routes(resource_name, param_name, resource_options, actions)
854
+ # When there are nested resources, use {param_name} for member routes to avoid
855
+ # API Gateway sibling path parameter conflicts. Without nested resources, use {id}.
856
+ has_nested = !block.nil?
857
+ add_scoped_resource_routes(resource_name, param_name, resource_options, actions, use_param_name: has_nested)
846
858
  build_nested_resource_block(resource_name, param_name, options, controller, &block) if block
847
859
  end
848
860
 
data/lib/belt/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Belt
4
- VERSION = '0.3.40'
4
+ VERSION = '0.3.41'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: belt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.40
4
+ version: 0.3.41
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stowzilla