3d004435b4
Previously, applications could only have two types of database configuration objects, `HashConfig` and `UrlConfig`. This meant that if you wanted your config to implement custom methods you had to monkey patch `DatabaseConfigurations` to take a custom class into account. This PR allows applications to register a custom db_config handler so that custom configs can respond to needed methods. This is especially useful for tools like Vitess where we may want to indicate it's sharded, but not give Rails direct access to that knowledge. Using the following database.yml as an example: ```yaml development: primary: database: my_db animals: database: my_animals_db vitess: sharded: 1 ``` We can register a custom handler that will generate `VitessConfig` objects instead of a `HashConfig` object in an initializer: ```ruby ActiveRecord::DatabaseConfigurations.register_db_config_handler do |env_name, name, url, config| next unless config.key?(:vitess) VitessConfig.new(env_name, name, config) end ``` and create the `VitessConfig` class: ```ruby class VitessConfig < ActiveRecord::DatabaseConfigurations::UrlConfig def sharded? vitess_config.fetch("sharded", false) end private def vitess_config configuration_hash.fetch(:vitess_config) end end ``` Now when the application is booted, the config with the `vitess` key will generate a `VitessConfig` object where all others will generate a `HashConfig`. Things to keep in mind: 1) It is recommended but not required that these custom configs inherit from Rails so you don't need to reimplement all the existing methods. 2) Applications must implement the configuration in which their config should be used, otherwise first config wins (so all their configs will be the custom one.) 3) The procs must support 4 arguments to accommodate `UrlConfig`. I am thinking of deprecating this and forcing the URL parsing to happen in the `UrlConfig` directly. 4) There is one tiny behavior change where when we have a nil url key in the config hash we no longer merge it back into the configuration hash. We also end up with a `HashConfig` instead of a `UrlConfig`. I think this is fine because a `nil` URL is...useless. Co-authored-by: John Crepezzi <john.crepezzi@gmail.com> |
||
---|---|---|
.. | ||
adapter_leasing_test.rb | ||
connection_handler_test.rb | ||
connection_handlers_multi_db_test.rb | ||
connection_handlers_multi_pool_config_test.rb | ||
connection_handlers_sharding_db_test.rb | ||
connection_swapping_nested_test.rb | ||
merge_and_resolve_default_url_config_test.rb | ||
mysql_type_lookup_test.rb | ||
schema_cache_test.rb | ||
standalone_connection_test.rb | ||
type_lookup_test.rb |