Class: ForestLiana::Engine

Inherits:
Rails::Engine
  • Object
show all
Defined in:
lib/forest_liana/engine.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.register_out_of_mount_hook_routesObject

An endpoint outside the engine mount can only be served by the host router: a route drawn in the engine gets prefixed with the mount, where no client ever calls. Prepended so a host catch-all (SPA fallback) cannot shadow the hooks, and registered from after_initialize rather than from config/routes/actions.rb, which is re-evaluated on every reload and would stack a duplicate block per pass — prepended blocks persist across reloads on their own. Defined here so the block's closure captures this empty scope, not after_initialize's locals: the block is retained by the router for the process lifetime and would otherwise pin the bootstrapper.



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/forest_liana/engine.rb', line 141

def self.register_out_of_mount_hook_routes
  Rails.application.routes.prepend do
    ForestLiana.apimap.each do |collection|
      collection.actions.each do |action|
        next if action.endpoint_under_forest_mount?

        post "#{action.absolute_endpoint}/hooks/load" => 'forest_liana/actions#load',
          action_name: ActiveSupport::Inflector.parameterize(action.name)
        if action.hooks && action.hooks[:change].present?
          post "#{action.absolute_endpoint}/hooks/change" => 'forest_liana/actions#change',
            action_name: ActiveSupport::Inflector.parameterize(action.name)
        end
      end
    end
  end
end

Instance Method Details

#configure_forest_corsObject



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/forest_liana/engine.rb', line 31

def configure_forest_cors
  begin
    rack_cors_class = Rack::Cors
    rack_cors_class = 'Rack::Cors' if Rails::VERSION::MAJOR < 5
    null_regex = Regexp.new(/\Anull\z/)

    config.middleware.insert_before 0, rack_cors_class do
      allow do
        hostnames = [null_regex, 'localhost:4200', /\A.*\.forestadmin\.com\z/]
        hostnames += ENV['CORS_ORIGINS'].split(',') if ENV['CORS_ORIGINS']

        origins hostnames
        resource ForestLiana::AuthenticationController::PUBLIC_ROUTES[1], headers: :any, methods: :any, credentials: true, max_age: 86400 # NOTICE: 1 day
      end

      allow do
        hostnames = ['localhost:4200', /\A.*\.forestadmin\.com\z/]
        hostnames += ENV['CORS_ORIGINS'].split(',') if ENV['CORS_ORIGINS']

        origins hostnames
        resource '*', headers: :any, methods: :any, credentials: true, max_age: 86400 # NOTICE: 1 day
      end
    end
    nil
  rescue => exception
    FOREST_REPORTER.report exception
    exception
  end
end

#database_available?Boolean

Returns:

  • (Boolean)


74
75
76
77
78
79
80
81
82
83
84
# File 'lib/forest_liana/engine.rb', line 74

def database_available?
  database_available = true
  begin
    ActiveRecord::Base.connection_pool.with_connection { |connection| connection.active? }
  rescue => error
    database_available = false
    FOREST_REPORTER.report error
    FOREST_LOGGER.error "No Apimap sent to Forest servers, it seems that the database is not accessible:\n#{error}"
  end
  database_available
end

#eager_load_active_record_descendants(app) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/forest_liana/engine.rb', line 88

def eager_load_active_record_descendants app
  # HACK: Force the ActiveRecord descendants classes from ActiveStorage to load for
  #       introspection.
  if defined? ActiveStorage
    ActiveStorage::Blob
    ActiveStorage::Attachment
  end

  if Rails::VERSION::MAJOR > 5 && Rails.autoloaders.zeitwerk_enabled?
    Zeitwerk::Loader.eager_load_all
  else
    app.eager_load!
  end
end

#rake?Boolean

Returns:

  • (Boolean)


61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/forest_liana/engine.rb', line 61

def rake?
  # NOTICE: `rails db:migrate` runs through Rake but exposes $0 as `rails`,
  #         so matching the binary name alone let the bootstrapper introspect
  #         models mid-migration (crashing on enums backed by a pending column).
  return true if File.basename($0) == 'rake'

  # NOTICE: `respond_to?` guard — the Rake constant can be defined with only a
  #         partial load (Rails' test_unit requires rake/file_list), leaving
  #         Rake.application undefined and crashing boot.
  defined?(Rake) && Rake.respond_to?(:application) &&
    Rake.application.top_level_tasks.any? { |task| task != 'default' }
end