Repository: rails/rails
File: activerecord/lib/active_record/database_configurations.rb (Ruby)

Code before:
  #
  # If you register a custom handler, objects will be created according to the
  # conditions of the handler. See ::register_db_config_handler for more on
  # registering custom handlers.
  class DatabaseConfigurations
    class InvalidConfigurationError < StandardError; end

    attr_reader :configurations
    delegate :any?, to: :configurations

    singleton_class.attr_accessor :db_config_handlers # :nodoc:
    self.db_config_handlers = [] # :nodoc:

    # Allows an application to register a custom handler for database configuration
    # objects. This is useful for creating a custom handler that responds to
    # methods your application needs but Active Record doesn't implement. For
    # example if you are using Vitess, you may want your Vitess configurations
    # to respond to `sharded?`. To implement this define the following in an
    # initializer:
    #
    #   ActiveRecord::DatabaseConfigurations.register_db_config_handler do |env_name, name, url, config|
    #     next unless config.key?(:vitess)
    #     VitessConfig.new(env_name, name, config)
    #   end
    #
    # Note: applications must handle the condition in which custom config should be
    # created in your handler registration otherwise all objects will use the custom
    # handler.
    #
    # Then define your +VitessConfig+ to respond to the methods your application
    # needs. It is recommended that you inherit from one of the existing
    # database config classes to avoid having to reimplement all methods. Custom
    # config handlers should only implement methods Active Record does not.
    #
    #   class VitessConfig < ActiveRecord::DatabaseConfigurations::UrlConfig
    #     def sharded?
    #       configuration_hash.fetch("sharded", false)
    #     end
    #   end
    #
    # For configs that have a +:vitess+ key, a +VitessConfig+ object will be
    # created instead of a +UrlConfig+.
    def self.register_db_config_handler(&block)
      db_config_handlers << block
    end

    register_db_config_handler do |env_name, name, url, config|
      if url
        UrlConfig.new(env_name, name, url, config)
      else
        HashConfig.new(env_name, name, config)

Review comment (suggestion):
Could this code example demonstrate the fact that the hook executes within the context of the `ActiveRecord::DatabaseConfigurations` class?

```diff
    #   ActiveSupport.on_load(:active_record_database_configurations) do
-   #     ActiveRecord::DatabaseConfigurations.register_db_config_handler do |env_name, name, url, config|
+   #     register_db_config_handler do |env_name, name, url, config|
    #       next unless config.key?(:vitess)
    #       VitessConfig.new(env_name, name, config)
    #     end
```

Code after:
  #
  # If you register a custom handler, objects will be created according to the
  # conditions of the handler. See ::register_db_config_handler for more on
  # registering custom handlers.
  class DatabaseConfigurations
    class InvalidConfigurationError < StandardError; end

    attr_reader :configurations
    delegate :any?, to: :configurations

    singleton_class.attr_accessor :db_config_handlers # :nodoc:
    self.db_config_handlers = [] # :nodoc:

    # Allows an application to register a custom handler for database configuration
    # objects. This is useful for creating a custom handler that responds to
    # methods your application needs but Active Record doesn't implement. For
    # example if you are using Vitess, you may want your Vitess configurations
    # to respond to `sharded?`. To implement this define the following in an
    # initializer:
    #
    #   ActiveSupport.on_load(:active_record_database_configurations) do
    #     ActiveRecord::DatabaseConfigurations.register_db_config_handler do |env_name, name, url, config|
    #       next unless config.key?(:vitess)
    #       VitessConfig.new(env_name, name, config)
    #     end
    #   end
    #
    # Note: applications must handle the condition in which custom config should be
    # created in your handler registration otherwise all objects will use the custom
    # handler.
    #
    # Then define your +VitessConfig+ to respond to the methods your application
    # needs. It is recommended that you inherit from one of the existing
    # database config classes to avoid having to reimplement all methods. Custom
    # config handlers should only implement methods Active Record does not.
    #
    #   class VitessConfig < ActiveRecord::DatabaseConfigurations::UrlConfig
    #     def sharded?
    #       configuration_hash.fetch("sharded", false)
    #     end
    #   end
    #
    # For configs that have a +:vitess+ key, a +VitessConfig+ object will be
    # created instead of a +UrlConfig+.
    def self.register_db_config_handler(&block)
      db_config_handlers << block
    end

    register_db_config_handler do |env_name, name, url, config|
      if url
        UrlConfig.new(env_name, name, url, config)