belt 0.3.36 → 0.3.38

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: 2e326b668a9c84c05be3a8b67b079fe62477131ea5d6bf7f641cc791c9ecf484
4
- data.tar.gz: 1d7d72326e7941a6fccb5474a9e659f72f62120e5b3212d0331c7d2229e99ab9
3
+ metadata.gz: 3e5d53661a4b6d4cc3c041c12f7ba7bd68683319eaf40d8a31c160c49d832014
4
+ data.tar.gz: 1e0ea7568414ad29a6219ae5b1c2f3506d589df6cfedce365f3feaee6aae44a4
5
5
  SHA512:
6
- metadata.gz: 2a5f09abb9d336b745fb4387b980c099436cf7b5a170b7ac48b0bce1e8104c964cb565213b1cd959edc498c8d1fbba491bd0066cf0d6dae45ef2ff89eaa9c31a
7
- data.tar.gz: 4ae1253f78503c66853b54de458f577e25c13a95e3616021264c25cbc7090ec389ec6aef7b2fc5bd6bbb28256509bda6a4e2b1a008b936969807efc35c7da9dd
6
+ metadata.gz: 5c9abf953818eacb858d5dda98c293c752ef07aaeef977e6914ddc6bccbbacd19992f8a762de131453fc8adf3cdbd121198e83d319961dee8e6cecb285a92f28
7
+ data.tar.gz: 8e09702c796419dcd1359b48ab6e7d30b41e233e737d834a35447c03483e62ac5474a6d6af3260dad9e5d60984c8e5c4127a491aaa6e8a8ae7642ab40babe9e9
data/CHANGELOG.md CHANGED
@@ -1,5 +1,121 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.38
4
+
5
+ ### Enhancement
6
+
7
+ - **Rails-like `namespace` inside nested resources**: The `NestedResourceBuilder`
8
+ now supports `namespace` blocks that add both a path prefix AND a controller
9
+ module prefix, just like Rails. This provides 99% Rails compatibility for
10
+ nested route organization.
11
+
12
+ ```ruby
13
+ resources :projects do
14
+ namespace :admin do
15
+ resources :users # → /projects/:project_id/admin/users → admin/users controller
16
+ end
17
+ end
18
+ ```
19
+
20
+ Namespaces can be nested and inherit auth/tables options:
21
+
22
+ ```ruby
23
+ resources :projects do
24
+ namespace :admin, auth: :iam, tables: [:audit_log] do
25
+ namespace :v2 do
26
+ resources :settings, only: [:index] # → admin/v2/settings controller
27
+ end
28
+ end
29
+ end
30
+ ```
31
+
32
+ - **`scope module:` option inside nested resources**: The existing `scope` method
33
+ now supports the `module:` option for Rails-like controller module prefixing
34
+ without adding a path prefix.
35
+
36
+ ```ruby
37
+ resources :projects do
38
+ scope module: 'v2' do
39
+ resources :users # → /projects/:project_id/users → v2/users controller
40
+ end
41
+ end
42
+ ```
43
+
44
+ ## 0.3.37
45
+
46
+ ### Enhancement
47
+
48
+ - **DRYer routing DSL with Rails-like `scope` inside nested resources**: The
49
+ `NestedResourceBuilder` now supports `scope` blocks for grouping routes with
50
+ shared options (path prefix, controller, tables, auth). This enables much
51
+ cleaner route definitions when multiple routes share the same controller or
52
+ tables.
53
+
54
+ **Before:**
55
+ ```ruby
56
+ resources :projects do
57
+ get 'billing', controller: :billing, action: :show, tables: [:memberships]
58
+ post 'billing/checkout', controller: :billing, action: :checkout, tables: [:memberships]
59
+ post 'billing/subscribe', controller: :billing, action: :subscribe, tables: [:memberships]
60
+ end
61
+ ```
62
+
63
+ **After:**
64
+ ```ruby
65
+ resources :projects do
66
+ scope path: 'billing', controller: :billing, tables: [:memberships] do
67
+ get '/', action: :show
68
+ post :checkout
69
+ post :subscribe
70
+ end
71
+ end
72
+ ```
73
+
74
+ - **Singular `resource` inside nested resources**: You can now use `resource`
75
+ (singular) inside a `resources` block for nested singular resources like
76
+ `:billing`, `:token_usage`, or `:profile`.
77
+
78
+ ```ruby
79
+ resources :projects do
80
+ resource :billing, only: [:show], tables: [:memberships]
81
+ resource :token_usage, only: [:show]
82
+ end
83
+ ```
84
+
85
+ - **Action inference from path**: When using symbol arguments or simple string
86
+ paths, the action is now inferred automatically. This works in `member`,
87
+ `collection`, and direct route definitions within resources.
88
+
89
+ ```ruby
90
+ resources :webhooks do
91
+ member do
92
+ post :test # action: :test inferred
93
+ end
94
+ end
95
+
96
+ resources :surfaces do
97
+ collection do
98
+ get :teams # action: :teams inferred
99
+ end
100
+ end
101
+
102
+ resources :projects do
103
+ post 'mark-complete' # action: :mark_complete inferred (hyphens → underscores)
104
+ end
105
+ ```
106
+
107
+ - **Controller inheritance in member/collection blocks**: Routes defined in
108
+ `member` and `collection` blocks now properly inherit the parent resource's
109
+ controller. This was inconsistent before and sometimes returned `nil`.
110
+
111
+ ```ruby
112
+ resources :webhooks do
113
+ member do
114
+ post :test # controller: 'webhooks' inherited
115
+ end
116
+ end
117
+ ```
118
+
3
119
  ## 0.3.32
4
120
 
5
121
  ### Enhancement
data/README.md CHANGED
@@ -209,6 +209,53 @@ end
209
209
 
210
210
  **Key point:** `namespace` and `scope` are purely organizational — they affect URL paths and controller module resolution but never change which Lambda handles the request. Use `function` when you need routes to go to a different Lambda.
211
211
 
212
+ ### Nested Resource DSL
213
+
214
+ Inside a `resources` block, you can use Rails-like `member`, `collection`, `scope`, and singular `resource` for DRYer route definitions:
215
+
216
+ ```ruby
217
+ Belt.application.routes.draw do
218
+ gateway :api do
219
+ resources :projects do
220
+ # Singular nested resource
221
+ resource :billing, only: [:show], tables: [:memberships]
222
+ resource :token_usage, only: [:show]
223
+
224
+ # Member routes (include /:id/)
225
+ resources :webhooks do
226
+ member do
227
+ post :test # → POST /projects/:project_id/webhooks/:webhook_id/test
228
+ end
229
+ end
230
+
231
+ # Collection routes (no /:id/)
232
+ resources :surfaces do
233
+ collection do
234
+ get :teams # → GET /projects/:project_id/surfaces/teams
235
+ end
236
+ member do
237
+ put :assign # → PUT /projects/:project_id/surfaces/:surface_id/assign
238
+ end
239
+ end
240
+
241
+ # Scope groups routes with shared options
242
+ scope path: 'billing', controller: :billing, tables: [:memberships] do
243
+ get '/', action: :show # → GET /projects/:project_id/billing
244
+ post :checkout # → POST /projects/:project_id/billing/checkout
245
+ post :subscribe
246
+ post :cancel
247
+ end
248
+ end
249
+ end
250
+ end
251
+ ```
252
+
253
+ **Key features:**
254
+ - **Action inference**: `:checkout` means both path segment and action name
255
+ - **Controller inheritance**: `member` and `collection` inherit parent resource's controller
256
+ - **Scope in nested context**: Group routes with shared path prefix, controller, tables, or auth
257
+ - **Singular `resource`**: For nested resources without an `:id` (billing, profile, etc.)
258
+
212
259
  ## BeltController Features
213
260
 
214
261
  ### Callbacks
@@ -148,7 +148,13 @@ module Belt
148
148
  # -- keyword options for destroy flags
149
149
  def initialize(generator, name, fields, force: false, skip_terraform: false, full: false, frontend_name: nil)
150
150
  @generator = generator
151
- @name = name&.downcase&.gsub(/[^a-z0-9_]/, '_')
151
+ # Environment names preserve hyphens (matching `belt g environment`);
152
+ # other generators normalize to underscores for valid Ruby identifiers.
153
+ @name = if generator == 'environment'
154
+ name&.downcase&.gsub(/[^a-z0-9_-]/, '')
155
+ else
156
+ name&.downcase&.gsub(/[^a-z0-9_]/, '_')
157
+ end
152
158
  @fields = fields
153
159
  @force = force
154
160
  @skip_terraform = skip_terraform
@@ -57,6 +57,111 @@ resources :comments, except: [:destroy]
57
57
  | POST | /profile | create |
58
58
  | DELETE | /profile | destroy |
59
59
 
60
+ ## Nested Resource DSL
61
+
62
+ Inside a `resources` block, you can use Rails-like `member`, `collection`, `scope`,
63
+ `namespace`, and singular `resource` for DRYer route definitions:
64
+
65
+ ```ruby
66
+ Belt.application.routes.draw do
67
+ gateway :api do
68
+ resources :projects do
69
+ # Singular nested resource (no :id in path)
70
+ resource :billing, only: [:show], tables: [:memberships]
71
+ resource :token_usage, only: [:show]
72
+
73
+ # Member routes (include /:id/)
74
+ resources :webhooks do
75
+ member do
76
+ post :test # → POST /projects/:project_id/webhooks/:webhook_id/test
77
+ end
78
+ end
79
+
80
+ # Collection routes (no /:id/)
81
+ resources :surfaces do
82
+ collection do
83
+ get :teams # → GET /projects/:project_id/surfaces/teams
84
+ end
85
+ member do
86
+ put :assign # → PUT /projects/:project_id/surfaces/:surface_id/assign
87
+ end
88
+ end
89
+
90
+ # Scope: groups routes with shared options
91
+ scope path: 'billing', controller: :billing, tables: [:memberships] do
92
+ get '/', action: :show # → GET /projects/:project_id/billing
93
+ post :checkout # → POST /projects/:project_id/billing/checkout
94
+ post :subscribe
95
+ post :cancel
96
+ end
97
+
98
+ # Namespace: adds path prefix AND controller module
99
+ namespace :admin do
100
+ resources :users # → /projects/:project_id/admin/users → admin/users controller
101
+ end
102
+ end
103
+ end
104
+ end
105
+ ```
106
+
107
+ ### Action Inference
108
+
109
+ Symbol paths automatically become the action name:
110
+
111
+ ```ruby
112
+ member do
113
+ post :test # path: /test, action: :test
114
+ end
115
+ post 'mark-complete' # path: /mark-complete, action: :mark_complete
116
+ ```
117
+
118
+ Hyphens in path segments convert to underscores in action names.
119
+
120
+ ### Controller Inheritance
121
+
122
+ Routes inside `member` and `collection` blocks inherit the parent resource's controller:
123
+
124
+ ```ruby
125
+ resources :surfaces do
126
+ member do
127
+ put :assign # controller: surfaces, action: assign
128
+ end
129
+ end
130
+ ```
131
+
132
+ Override with the `controller:` option:
133
+
134
+ ```ruby
135
+ member do
136
+ get :billing, controller: :project_billing
137
+ end
138
+ ```
139
+
140
+ ### Namespace vs Scope
141
+
142
+ | Feature | `namespace` | `scope` |
143
+ |---------|-------------|---------|
144
+ | Path prefix | ✓ | Optional (`path:`) |
145
+ | Controller module | ✓ | Optional (`module:`) |
146
+ | Use case | Rails-like module nesting | Flexible grouping |
147
+
148
+ ```ruby
149
+ # Namespace: path + controller module
150
+ namespace :admin do
151
+ resources :users # → /admin/users → admin/users controller
152
+ end
153
+
154
+ # Scope with path only (no controller change)
155
+ scope path: 'v2' do
156
+ resources :users # → /v2/users → users controller
157
+ end
158
+
159
+ # Scope with module only (no path change)
160
+ scope module: 'legacy' do
161
+ resources :users # → /users → legacy/users controller
162
+ end
163
+ ```
164
+
60
165
  ## Namespace and Scope
61
166
 
62
167
  ```ruby
@@ -52,7 +52,7 @@ module Belt
52
52
 
53
53
  class NestedResourceBuilder
54
54
  def initialize(gateway, prefix, collection_prefix, inherited_tables: [], inherited_auth: nil, # rubocop:disable Metrics/ParameterLists
55
- inherited_controller: nil, inherited_lambda: nil)
55
+ inherited_controller: nil, inherited_lambda: nil, scope_module: nil)
56
56
  @gateway = gateway
57
57
  @prefix = prefix
58
58
  @collection_prefix = collection_prefix
@@ -60,6 +60,7 @@ module Belt
60
60
  @inherited_auth = inherited_auth
61
61
  @inherited_controller = inherited_controller
62
62
  @inherited_lambda = inherited_lambda
63
+ @scope_module = scope_module
63
64
  end
64
65
 
65
66
  def resources(name, options = {}, &block)
@@ -67,7 +68,10 @@ module Belt
67
68
  singular = @gateway.send(:singularize, resource_name)
68
69
  param_name = options[:param] || "#{singular}_id"
69
70
  options = options.merge(tables: [resource_name.to_sym]) unless options.key?(:tables)
70
- options = merge_inherited_options(options)
71
+ # Compute controller FIRST: explicit > scope_module/resource > resource_name
72
+ # Don't inherit controller from parent resource — nested resources get their own controller
73
+ controller_name = options[:controller] || compute_controller_name(resource_name)
74
+ options = merge_inherited_options(options.merge(controller: controller_name))
71
75
  resource_options = options.merge(route_type: :resources)
72
76
  actions = @gateway.send(:determine_actions, options)
73
77
 
@@ -76,14 +80,107 @@ module Belt
76
80
 
77
81
  nested_member_prefix = "#{@prefix}/#{resource_name}/{#{param_name}}"
78
82
  nested_collection_prefix = "#{@prefix}/#{resource_name}"
83
+ # Pass scope_module to nested builder so nested resources inherit it
79
84
  nested_builder = NestedResourceBuilder.new(@gateway, nested_member_prefix, nested_collection_prefix,
80
85
  inherited_tables: Array(options[:tables] || []),
81
86
  inherited_auth: options[:auth] || @inherited_auth,
82
- inherited_controller: @inherited_controller,
83
- inherited_lambda: @inherited_lambda)
87
+ inherited_controller: controller_name,
88
+ inherited_lambda: @inherited_lambda,
89
+ scope_module: @scope_module)
84
90
  nested_builder.instance_eval(&block)
85
91
  end
86
92
 
93
+ # Singular resource inside nested context (e.g. resource :billing inside resources :projects)
94
+ def resource(name, options = {})
95
+ resource_name = name.to_s
96
+ # Compute controller FIRST: explicit > scope_module/resource > resource_name
97
+ # Don't inherit controller from parent resource — singular resources get their own controller
98
+ controller_name = options[:controller] || compute_controller_name(resource_name)
99
+ options = merge_inherited_options(options.merge(controller: controller_name))
100
+ resource_options = options.merge(route_type: :resource)
101
+ actions = determine_actions(options, default: %i[show update destroy create])
102
+
103
+ if actions.include?(:show)
104
+ @gateway.send(:add_route, :get, join_path(@prefix, resource_name),
105
+ resolve_request_model_for(resource_options, :show))
106
+ end
107
+ if actions.include?(:update)
108
+ @gateway.send(:add_route, :put, join_path(@prefix, resource_name),
109
+ resolve_request_model_for(resource_options, :update))
110
+ end
111
+ if actions.include?(:destroy)
112
+ @gateway.send(:add_route, :delete, join_path(@prefix, resource_name),
113
+ resolve_request_model_for(resource_options, :destroy))
114
+ end
115
+ return unless actions.include?(:create)
116
+
117
+ @gateway.send(:add_route, :post, join_path(@prefix, resource_name),
118
+ resolve_request_model_for(resource_options, :create))
119
+ end
120
+
121
+ # Rails-like `namespace` inside nested resource context — adds both a path prefix
122
+ # AND sets the controller module. Resources inside inherit the namespace module.
123
+ #
124
+ # Example:
125
+ # resources :projects do
126
+ # namespace :admin do
127
+ # resources :users # → /projects/:project_id/admin/users → admin/users controller
128
+ # end
129
+ # end
130
+ def namespace(name, options = {}, &)
131
+ segment = name.to_s
132
+ # namespace sets path AND module (controller prefix)
133
+ merged = { path: segment, module: segment }.merge(options)
134
+ scope(merged, &)
135
+ end
136
+
137
+ # Scope inside nested resource context - groups routes with shared options
138
+ # Example:
139
+ # resources :projects do
140
+ # scope path: 'billing', controller: :billing, tables: [:memberships] do
141
+ # get '/', action: :show
142
+ # post :checkout
143
+ # end
144
+ # end
145
+ #
146
+ # With module option (like Rails):
147
+ # resources :projects do
148
+ # scope module: 'v2' do
149
+ # resources :users # → /projects/:project_id/users → v2/users controller
150
+ # end
151
+ # end
152
+ def scope(options = {}, &)
153
+ previous_prefix = @prefix
154
+ previous_collection_prefix = @collection_prefix
155
+ previous_tables = @inherited_tables
156
+ previous_auth = @inherited_auth
157
+ previous_controller = @inherited_controller
158
+ previous_module = @scope_module
159
+
160
+ if options.key?(:path)
161
+ segment = options[:path].to_s.gsub(%r{^/|/$}, '')
162
+ @prefix = join_path(@prefix, segment)
163
+ @collection_prefix = join_path(@collection_prefix, segment)
164
+ end
165
+ # Module sets the controller prefix for nested resources (like Rails)
166
+ if options.key?(:module)
167
+ mod_segment = options[:module].to_s
168
+ @scope_module = @scope_module.to_s.empty? ? mod_segment : "#{@scope_module}/#{mod_segment}"
169
+ end
170
+ @inherited_auth = options[:auth] || @inherited_auth
171
+ @inherited_tables = (@inherited_tables + Array(options[:tables] || [])).uniq
172
+ @inherited_controller = options[:controller]&.to_s || @inherited_controller
173
+
174
+ instance_eval(&) if block_given?
175
+
176
+ @prefix = previous_prefix
177
+ @collection_prefix = previous_collection_prefix
178
+ @inherited_tables = previous_tables
179
+ @inherited_auth = previous_auth
180
+ @inherited_controller = previous_controller
181
+ @scope_module = previous_module
182
+ end
183
+
87
184
  def member(&)
88
185
  MemberCollectionBuilder.new(@gateway, @prefix, @inherited_tables, @inherited_auth,
89
186
  @inherited_controller, @inherited_lambda).instance_eval(&)
@@ -95,16 +192,65 @@ module Belt
95
192
  end
96
193
 
97
194
  %i[get post put delete patch].each do |method|
98
- define_method(method) do |path, options = {}|
99
- full_path = options[:on] == :collection ? "#{@collection_prefix}#{path}" : "#{@prefix}#{path}"
195
+ define_method(method) do |path_or_action, options = {}|
196
+ # Support both symbol (action name = path) and string (explicit path)
197
+ path, action = normalize_path_and_action(path_or_action, options)
198
+ base = options[:on] == :collection ? @collection_prefix : @prefix
199
+ full_path = join_path(base, path)
100
200
  options = merge_inherited_options(options)
101
201
  route_options = options.except(:on)
202
+ route_options[:action] ||= action if action
102
203
  @gateway.send(:add_route, method, full_path, route_options)
103
204
  end
104
205
  end
105
206
 
106
207
  private
107
208
 
209
+ # Normalize path/action: symbol means path=action, string means infer action from path
210
+ def normalize_path_and_action(path_or_action, options)
211
+ return [options[:path] || '', options[:action]] if path_or_action.nil?
212
+
213
+ if path_or_action.is_a?(Symbol)
214
+ # Symbol: use as both path segment and action name (e.g. :checkout → path: 'checkout', action: :checkout)
215
+ [path_or_action.to_s, options[:action] || path_or_action]
216
+ else
217
+ path = path_or_action.to_s
218
+ # Infer action from last non-param segment of path (e.g. 'checkout' → :checkout, '/' → nil)
219
+ inferred_action = options[:action] || infer_action_from_path(path)
220
+ [path, inferred_action]
221
+ end
222
+ end
223
+
224
+ # Infer action name from path: 'checkout' → :checkout, 'billing/checkout' → :checkout
225
+ def infer_action_from_path(path)
226
+ return nil if path.nil? || path.empty? || path == '/'
227
+
228
+ segments = path.gsub(%r{^/|/$}, '').split('/')
229
+ # Find last segment that's not a parameter (doesn't contain {})
230
+ last_segment = segments.reverse.find { |s| !s.include?('{') }
231
+ last_segment&.tr('-', '_')&.to_sym
232
+ end
233
+
234
+ # Join a base path with a relative path, ensuring exactly one `/` separator.
235
+ # Handles "/" path by returning just the base (no trailing slash).
236
+ def join_path(base, path)
237
+ path = path.to_s
238
+ return base if path.empty? || path == '/'
239
+ return "#{base}#{path}".chomp('/') if path.start_with?('/')
240
+
241
+ "#{base}/#{path}"
242
+ end
243
+
244
+ def determine_actions(options, default: %i[index create show update destroy])
245
+ if options[:only]
246
+ Array(options[:only])
247
+ elsif options[:except]
248
+ default - Array(options[:except])
249
+ else
250
+ default
251
+ end
252
+ end
253
+
108
254
  def add_nested_resource_routes(resource_name, param_name, resource_options, actions)
109
255
  if actions.include?(:index)
110
256
  @gateway.send(:add_route, :get, "#{@prefix}/#{resource_name}",
@@ -150,6 +296,17 @@ module Belt
150
296
  result[:lambda] ||= @inherited_lambda if @inherited_lambda
151
297
  result
152
298
  end
299
+
300
+ # Compute controller name from scope_module and resource name
301
+ # If scope_module is set, returns "module/resource_name" (Rails-like)
302
+ # Otherwise returns just resource_name
303
+ def compute_controller_name(resource_name)
304
+ if @scope_module && !@scope_module.empty?
305
+ "#{@scope_module}/#{resource_name}"
306
+ else
307
+ resource_name
308
+ end
309
+ end
153
310
  end
154
311
 
155
312
  class MemberCollectionBuilder
@@ -164,15 +321,53 @@ module Belt
164
321
  end
165
322
 
166
323
  %i[get post put delete patch].each do |method|
167
- define_method(method) do |path, options = {}|
168
- full_path = "#{@prefix}#{path}"
324
+ define_method(method) do |path_or_action, options = {}|
325
+ # Support both symbol (action name = path) and string (explicit path)
326
+ path, action = normalize_path_and_action(path_or_action, options)
327
+ full_path = join_path(@prefix, path)
169
328
  options = merge_inherited_options(options)
329
+ options[:action] ||= action if action
170
330
  @gateway.send(:add_route, method, full_path, options)
171
331
  end
172
332
  end
173
333
 
174
334
  private
175
335
 
336
+ # Normalize path/action: symbol means path=action, string means infer action from path
337
+ def normalize_path_and_action(path_or_action, options)
338
+ return ['', options[:action]] if path_or_action.nil?
339
+
340
+ if path_or_action.is_a?(Symbol)
341
+ # Symbol: use as both path segment and action name (e.g. :test → path: 'test', action: :test)
342
+ [path_or_action.to_s, options[:action] || path_or_action]
343
+ else
344
+ path = path_or_action.to_s
345
+ # Infer action from last non-param segment of path (e.g. 'test' → :test)
346
+ inferred_action = options[:action] || infer_action_from_path(path)
347
+ [path, inferred_action]
348
+ end
349
+ end
350
+
351
+ # Infer action name from path: 'test' → :test, 'deep/nested' → :nested
352
+ def infer_action_from_path(path)
353
+ return nil if path.nil? || path.empty? || path == '/'
354
+
355
+ segments = path.gsub(%r{^/|/$}, '').split('/')
356
+ # Find last segment that's not a parameter (doesn't contain {})
357
+ last_segment = segments.reverse.find { |s| !s.include?('{') && !s.start_with?(':') }
358
+ last_segment&.tr('-', '_')&.to_sym
359
+ end
360
+
361
+ # Join a base path with a relative path, ensuring exactly one `/` separator.
362
+ # Handles "/" path by returning just the base (no trailing slash).
363
+ def join_path(base, path)
364
+ path = path.to_s
365
+ return base if path.empty? || path == '/'
366
+ return "#{base}#{path}".chomp('/') if path.start_with?('/')
367
+
368
+ "#{base}/#{path}"
369
+ end
370
+
176
371
  def merge_inherited_options(options)
177
372
  result = options.dup
178
373
  if @inherited_tables.any?
@@ -230,9 +425,11 @@ module Belt
230
425
  inherited_tables = (@default_tables + resource_tables).uniq
231
426
  inherited_auth = options[:auth] || @default_auth
232
427
  inherited_lambda = options[:lambda]
428
+ inherited_controller = resource_name
233
429
  nested_builder = NestedResourceBuilder.new(self, member_prefix, collection_prefix,
234
430
  inherited_tables: inherited_tables,
235
431
  inherited_auth: inherited_auth,
432
+ inherited_controller: inherited_controller,
236
433
  inherited_lambda: inherited_lambda)
237
434
  nested_builder.instance_eval(&)
238
435
  end
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.36'
4
+ VERSION = '0.3.38'
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.36
4
+ version: 0.3.38
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stowzilla