class Dry::Rails::Railtie

The railtie is responsible for setting up a container and handling reloading in dev mode

@api public

Public Instance Methods

app_namespace() click to toggle source

Infer the default application namespace

TODO: we had to rename namespace=>app_namespace because

Rake::DSL's Kernel#namespace *sometimes* breaks things.
Currently we are missing specs verifying that rake tasks work
correctly and those must be added!

@return [Module]

@api public

# File lib/dry/rails/railtie.rb, line 113
def app_namespace
  @app_namespace ||= begin
    top_level_namespace = ::Rails.application.class.to_s.split("::").first
    Object.const_get(top_level_namespace)
  end
end
container() click to toggle source

Exposes the container constant

@return [Dry::Rails::Container]

@api public

# File lib/dry/rails/railtie.rb, line 80
def container
  app_namespace.const_get(:Container, false)
end
default_inflector() click to toggle source

Sets or reloads a constant within the application namespace

@api private

# File lib/dry/rails/railtie.rb, line 123
def default_inflector
  ActiveSupport::Inflector
end
finalize!() click to toggle source

Code-reloading-aware finalization process

This sets up `Container` and `Deps` constants, reloads them if this is in reloading mode, and registers default components like the railtie itself or the inflector

@api public

rubocop:disable Metrics/AbcSize

# File lib/dry/rails/railtie.rb, line 25
def finalize!
  stop_features if reloading?

  root_path = ::Rails.root

  container = Dry::Rails.create_container(
    root: root_path,
    name: name,
    default_namespace: name.to_s,
    inflector: default_inflector,
    system_dir: root_path.join("config/system"),
    bootable_dirs: [root_path.join("config/system/boot")]
  )

  # Enable :env plugin by default because it is a very common requirement
  container.use :env, inferrer: -> { ::Rails.env }

  container.register(:railtie, self)
  container.register(:inflector, default_inflector)

  set_or_reload(:Container, container)

  Dry::Rails.evaluate_initializer(container)

  set_or_reload(container.auto_inject_constant, container.injector)

  container.features.each do |feature|
    container.boot(feature, from: :rails)
  end

  container.refresh_boot_files if reloading?

  container.finalize!(freeze: !::Rails.env.test?)
end
Also aliased as: reload
name() click to toggle source

Return the default system name

In the dry-system world containers are explicitly named using symbols, so that you can refer to them easily when ie importing one container into another

@return [Symbol]

@api private

# File lib/dry/rails/railtie.rb, line 99
def name
  app_namespace.name.underscore.to_sym
end
reload()

rubocop:enable Metrics/AbcSize

Alias for: finalize!
reloading?() click to toggle source

Return true if we're in code-reloading mode

@api private

# File lib/dry/rails/railtie.rb, line 87
def reloading?
  app_namespace.const_defined?(:Container, false)
end
remove_constant(const_name) click to toggle source

@api private

# File lib/dry/rails/railtie.rb, line 137
def remove_constant(const_name)
  app_namespace.__send__(:remove_const, const_name)
end
set_or_reload(const_name, const) click to toggle source

@api private

# File lib/dry/rails/railtie.rb, line 128
def set_or_reload(const_name, const)
  if app_namespace.const_defined?(const_name, false)
    app_namespace.__send__(:remove_const, const_name)
  end

  app_namespace.const_set(const_name, const)
end
stop_features() click to toggle source

Stops all configured features (bootable components)

This is crucial when reloading code in development mode. Every bootable component should be able to clear the runtime from any constants that it created in its `stop` lifecycle step

@api public

# File lib/dry/rails/railtie.rb, line 69
def stop_features
  container.features.each do |feature|
    container.stop(feature) if container.booted?(feature)
  end
end