Module: Brick::RouteSet

Defined in:
lib/brick.rb

Instance Method Summary collapse

Instance Method Details

#finalize!Object



564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
# File 'lib/brick.rb', line 564

def finalize!
  unless ::Rails.application.routes.named_routes.route_defined?(:brick_status_path)
    path_prefix = ::Brick.config.path_prefix
    existing_controllers = routes.each_with_object({}) do |r, s|
      c = r.defaults[:controller]
      s[c] = nil if c
    end
    ::Rails.application.routes.append do
      tables = []
      views = []
      table_class_length = 38 # Length of "Classes that can be built from tables:"
      view_class_length = 37 # Length of "Classes that can be built from views:"

      brick_routes_create = lambda do |schema_name, controller_name, v, options|
        if schema_name # && !Object.const_defined('Apartment')
          send(:namespace, schema_name) do
            send(:resources, v[:resource].to_sym, **options)
          end
        else
          send(:resources, v[:resource].to_sym, **options)
        end
      end

      # %%% TODO: If no auto-controllers then enumerate the controllers folder in order to build matching routes
      # If auto-controllers and auto-models are both enabled then this makes sense:
      controller_prefix = (path_prefix ? "#{path_prefix}/" : '')
      ::Brick.relations.each do |k, v|
        unless !(controller_name = v.fetch(:resource, nil)&.pluralize) || existing_controllers.key?(controller_name)
          options = {}
          options[:only] = [:index, :show] if v.key?(:isView)
          # First do the API routes
          full_resource = nil
          if (schema_name = v.fetch(:schema, nil))
            full_resource = "#{schema_name}/#{v[:resource]}"
            send(:get, "#{::Brick.api_root}#{full_resource}", { to: "#{controller_prefix}#{schema_name}/#{controller_name}#index" }) if Object.const_defined?('Rswag::Ui')
          else
            # Normally goes to something like:  /api/v1/employees
            send(:get, "#{::Brick.api_root}#{v[:resource]}", { to: "#{controller_prefix}#{controller_name}#index" }) if Object.const_defined?('Rswag::Ui')
          end
          # Now the normal routes
          if path_prefix
            # Was:  send(:scope, path: path_prefix) do
            send(:namespace, path_prefix) do
              brick_routes_create.call(schema_name, controller_name, v, options)
            end
          else
            brick_routes_create.call(schema_name, controller_name, v, options)
          end

          if (class_name = v.fetch(:class_name, nil))
            if v.key?(:isView)
              view_class_length = class_name.length if class_name.length > view_class_length
              views
            else
              table_class_length = class_name.length if class_name.length > table_class_length
              tables
            end << [class_name, full_resource || v[:resource]]
          end
        end
      end

      if ::Brick.config.add_status && instance_variable_get(:@set).named_routes.names.exclude?(:brick_status)
        get("/#{controller_prefix}brick_status", to: 'brick_gem#status', as: 'brick_status')
      end

      if ::Brick.config.add_orphans && instance_variable_get(:@set).named_routes.names.exclude?(:brick_orphans)
        get("/#{controller_prefix}brick_orphans", to: 'brick_gem#orphans', as: 'brick_orphans')
      end

      unless ::Brick.routes_done
        if Object.const_defined?('Rswag::Ui')
          rswag_path = ::Rails.application.routes.routes.find { |r| r.app.app == Rswag::Ui::Engine }&.instance_variable_get(:@path_formatter)&.instance_variable_get(:@parts)&.join
          if (doc_endpoint = Rswag::Ui.config.config_object[:urls]&.last)
            puts "Mounting OpenApi 3.0 documentation endpoint for \"#{doc_endpoint[:name]}\" on #{doc_endpoint[:url]}"
            send(:get, doc_endpoint[:url], { to: 'brick_openapi#index' })
            endpoint_parts = doc_endpoint[:url]&.split('/')
            if rswag_path && endpoint_parts
              puts "API documentation now available when navigating to:  /#{endpoint_parts&.find(&:present?)}/index.html"
            else
              puts "In order to make documentation available you can put this into your routes.rb:"
              puts "  mount Rswag::Ui::Engine => '/#{endpoint_parts&.find(&:present?) || 'api-docs'}'"
            end
          else
            sample_path = rswag_path || '/api-docs'
            puts
            puts "Brick:  rswag-ui gem detected -- to make OpenAPI 3.0 documentation available from a path such as  '#{sample_path}/v1/swagger.json',"
            puts '        put code such as this in an initializer:'
            puts '  Rswag::Ui.configure do |config|'
            puts "    config.swagger_endpoint '#{sample_path}/v1/swagger.json', 'API V1 Docs'"
            puts '  end'
            unless rswag_path
              puts
              puts '        and put this into your routes.rb:'
              puts "  mount Rswag::Ui::Engine => '/api-docs'"
            end
          end
        end

        ::Brick.routes_done = true
        puts "\n" if tables.present? || views.present?
        if tables.present?
          puts "Classes that can be built from tables:#{' ' * (table_class_length - 38)}  Path:"
          puts "======================================#{' ' * (table_class_length - 38)}  ====="
          ::Brick.display_classes(controller_prefix, tables, table_class_length)
        end
        if views.present?
          puts "Classes that can be built from views:#{' ' * (view_class_length - 37)}  Path:"
          puts "=====================================#{' ' * (view_class_length - 37)}  ====="
          ::Brick.display_classes(controller_prefix, views, view_class_length)
        end
      end
    end
  end
  super
end