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.



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

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



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

def lambda(name, &)
  name
end

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



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

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



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

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



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

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



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

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



384
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
# File 'lib/belt/route_dsl.rb', line 384

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



351
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
# File 'lib/belt/route_dsl.rb', line 351

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



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

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