• E
    Basic API for connection switching · 31021a8c
    Eileen Uchitelle 提交于
    This PR adds the ability to 1) connect to multiple databases in a model,
    and 2) switch between those connections using a block.
    
    To connect a model to a set of databases for writing and reading use
    the following API. This API supercedes `establish_connection`. The
    `writing` and `reading` keys represent handler / role names and
    `animals` and `animals_replica` represents the database key to look up
    the configuration hash from.
    
    ```
    class AnimalsBase < ApplicationRecord
      connects_to database: { writing: :animals, reading: :animals_replica }
    end
    ```
    
    Inside the application - outside the model declaration - we can switch
    connections with a block call to `connected_to`.
    
    If we want to connect to a db that isn't default (ie readonly_slow) we
    can connect like this:
    
    Outside the model we may want to connect to a new database (one that is
    not in the default writing/reading set) - for example a slow replica for
    making slow queries. To do this we have the `connected_to` method that
    takes a `database` hash that matches the signature of `connects_to`. The
    `connected_to` method also takes a block.
    
    ```
    AcitveRecord::Base.connected_to(database: { slow_readonly: :primary_replica_slow }) do
      ModelInPrimary.do_something_thats_slow
    end
    ```
    
    For models that are already loaded and connections that are already
    connected, `connected_to` doesn't need to pass in a `database` because
    you may want to run queries against multiple databases using a specific
    role/handler.
    
    In this case `connected_to` can take a `role` and use that to swap on
    the connection passed. This simplies queries - and matches how we do it
    in GitHub. Once you're connected to the database you don't need to
    re-connect, we assume the connection is in the pool and simply pass the
    handler we'd like to swap on.
    
    ```
    ActiveRecord::Base.connected_to(role: :reading) do
      Dog.read_something_from_dog
      ModelInPrimary.do_something_from_model_in_primary
    end
    ```
    31021a8c
core.rb 20.4 KB