Class: Belt::Application::RouteBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/belt/route_dsl.rb

Instance Method Summary collapse

Constructor Details

#initialize(gateway) ⇒ RouteBuilder

Returns a new instance of RouteBuilder.



302
303
304
305
306
307
308
309
# File 'lib/belt/route_dsl.rb', line 302

def initialize(gateway)
  @gateway = gateway
  @scope_prefix = ''
  @scope_module = nil
  @scope_auth = nil
  @scope_tables = []
  @scope_controller = nil
end

Instance Method Details

#lambda(name) ⇒ Object



412
413
414
# File 'lib/belt/route_dsl.rb', line 412

def lambda(name, &)
  name
end

#mount(mountable, options = {}) ⇒ Object



416
417
418
419
420
421
422
423
424
425
# File 'lib/belt/route_dsl.rb', line 416

def mount(mountable, options = {})
  prefix = options[:at]&.to_s&.gsub(%r{^/|/$}, '') || ''
  extra_tables = Array(options[:tables] || [])
  auth_override = options[:auth]
  route_definitions = mountable.respond_to?(:routes) ? mountable.routes : []

  route_definitions.each do |route_def|
    mount_route(route_def, prefix, extra_tables, auth_override)
  end
end

#mount_full_path(path, prefix) ⇒ Object



436
437
438
439
440
# File 'lib/belt/route_dsl.rb', line 436

def mount_full_path(path, prefix)
  full_path = prefix.empty? ? path : "/#{prefix}#{path}"
  full_path = full_path.chomp('/') unless full_path == '/'
  build_path(full_path)
end

#mount_route(route_def, prefix, extra_tables, auth_override) ⇒ Object



427
428
429
430
431
432
433
434
# File 'lib/belt/route_dsl.rb', line 427

def mount_route(route_def, prefix, extra_tables, auth_override)
  method = route_def[:method].to_sym
  path = route_def[:path].to_s.gsub(/:([a-zA-Z_]\w*)/) { "{#{::Regexp.last_match(1)}}" }
  full_path = mount_full_path(path, prefix)
  route_options = mount_route_options(route_def, path, prefix, extra_tables, auth_override)

  @gateway.send(method, full_path, route_options)
end

#mount_route_options(route_def, path, prefix, extra_tables, auth_override) ⇒ Object



442
443
444
445
446
447
448
449
450
451
452
# File 'lib/belt/route_dsl.rb', line 442

def mount_route_options(route_def, path, prefix, extra_tables, auth_override)
  route_options = (route_def[:options] || {}).dup
  route_options[:tables] = (extra_tables + Array(route_options[:tables] || [])).uniq
  route_options[:auth] = auth_override if auth_override
  route_options[:auth] ||= @scope_auth if @scope_auth
  route_options[:tables] = (@scope_tables + route_options[:tables]).uniq if @scope_tables.any?
  route_options[:controller] ||= prefix.gsub('-', '_') unless prefix.empty?
  stripped = path.gsub(%r{^/|/$}, '')
  route_options[:action] ||= stripped.empty? ? 'index' : stripped.gsub('-', '_')
  route_options
end

#resource(name, options = {}) ⇒ Object



385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
# File 'lib/belt/route_dsl.rb', line 385

def resource(name, options = {})
  options = apply_scope_options(options)

  if @scope_prefix.empty?
    @gateway.resource(name, options)
  else
    resource_name = name.to_s
    controller = "#{@scope_prefix}/#{resource_name}"
    resource_options = options.merge(route_type: :resource, controller: controller)
    actions = determine_scoped_actions(options, default: %i[show update destroy create])

    @gateway.send(:add_route, :get, build_path("/#{resource_name}"), resource_options) if actions.include?(:show)
    if actions.include?(:update)
      @gateway.send(:add_route, :put, build_path("/#{resource_name}"),
                    resource_options)
    end
    if actions.include?(:destroy)
      @gateway.send(:add_route, :delete, build_path("/#{resource_name}"),
                    resource_options)
    end
    if actions.include?(:create)
      @gateway.send(:add_route, :post, build_path("/#{resource_name}"),
                    resource_options)
    end
  end
end

#resources(name, options = {}, &block) ⇒ Object



352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
# File 'lib/belt/route_dsl.rb', line 352

def resources(name, options = {}, &block)
  options = apply_scope_options(options)

  if @scope_prefix.empty?
    @gateway.resources(name, options, &block)
  else
    # When inside a scope, generate routes with the prefix applied.
    # Also set the controller explicitly so inference resolves correctly
    # (e.g., scope "admin" + resources :users → controller "admin/users").
    resource_name = name.to_s
    singular = Belt::Inflector.singularize(resource_name)
    param_name = options[:param] || "#{singular}_id"
    controller = "#{@scope_prefix}/#{resource_name}"
    resource_options = options.merge(route_type: :resources, controller: controller)
    actions = determine_scoped_actions(options)

    add_scoped_resource_routes(resource_name, param_name, resource_options, actions)

    if block
      collection_prefix = build_path("/#{resource_name}")
      member_prefix = build_path("/#{resource_name}/{#{param_name}}")
      resource_tables = Array(options[:tables] || [])
      inherited_tables = (@gateway.default_tables + resource_tables).uniq
      inherited_auth = options[:auth] || @gateway.default_auth
      nested_builder = NestedResourceBuilder.new(@gateway, member_prefix, collection_prefix,
                                                 inherited_tables: inherited_tables,
                                                 inherited_auth: inherited_auth,
                                                 inherited_controller: controller)
      nested_builder.instance_eval(&block)
    end
  end
end

#scope(options = {}) ⇒ Object



311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
# File 'lib/belt/route_dsl.rb', line 311

def scope(options = {}, &)
  previous_prefix = @scope_prefix
  previous_module = @scope_module
  previous_auth = @scope_auth
  previous_tables = @scope_tables
  previous_controller = @scope_controller

  # Nest path segments (Rails-style): scope path: "a" { scope path: "b" } → "a/b"
  if options.key?(:path)
    segment = options[:path].to_s.gsub(%r{^/|/$}, '')
    @scope_prefix = @scope_prefix.to_s.empty? ? segment : "#{@scope_prefix}/#{segment}"
  end
  @scope_module = options[:module] || @scope_module
  @scope_auth = options[:auth] || @scope_auth
  @scope_tables = (@scope_tables + Array(options[:tables] || [])).uniq
  @scope_controller = options[:controller] || @scope_controller

  instance_eval(&) if block_given?

  @scope_prefix = previous_prefix
  @scope_module = previous_module
  @scope_auth = previous_auth
  @scope_tables = previous_tables
  @scope_controller = previous_controller
end