1. 15 4月, 2020 1 次提交
  2. 14 4月, 2020 1 次提交
    • J
      Prevent has_one from touching parent record unless persisted · ba3ef762
      Josh 提交于
      Previously, if `build_association` was called multiple times for a `has_one` association but never committed to the database, the first newly-associated record would trigger `touch` during the attempted removal of the record.
      
      For example:
      
          class Post < ActiveRecord::Base
            has_one :comment, inverse_of: :post, dependent: :destroy
          end
      
          class Comment < ActiveRecord::Base
            belongs_to :post, inverse_of: :comment, touch: true
          end
      
          post = Post.create!
          comment_1 = post.build_comment
          comment_2 = post.build_comment
      
      When `comment_2` is initialized, the `has_one` would attempt to destroy `comment_1`, triggering a `touch` on `post` from an association record that hasn't been committed to the database.
      
      This removes the attempt to delete an associated `has_one` unless it’s persisted.
      ba3ef762
  3. 29 3月, 2020 1 次提交
    • P
      Add support for `if_not_exists` to indexes · 7ba08037
      Prathamesh Sonpatki 提交于
      When we try to create a table which already exists which also adds
      indexes, then the `if_not_exists` option passed to `create_table` is
      not extended to indexes. So the migration results into an error if the
      table and indexes already exist.
      This change extends the `if_not_exists` support to `add_index` so that
      if the migration tries to create a table which also has existing
      indexes, error won't be raised.
      Also as a side-effect individual `add_index` calls will also accept
      `if_not_exists` option and respect it henceforth.
      
      [Prathamesh Sonpatki, Justin George]
      7ba08037
  4. 27 3月, 2020 1 次提交
  5. 25 3月, 2020 1 次提交
  6. 21 3月, 2020 1 次提交
  7. 20 3月, 2020 1 次提交
    • E
      Handle db:rollback and db:rollback:[NAME] for multi-db apps · e33075a0
      eileencodes 提交于
      With a multiple database application `db:rollback` becomes problematic.
      We can't rollback just the primary, that doesn't match the behavior in
      the other tasks. We can't rollback a migration for every database, that
      is unexpected.
      
      To solve this I handled `db:rollback` the same way I handled `:up` and
      `:down`. If `db:rollback` is called for a multi-db application then it
      will raise an error recommending you use `db:rollback:[NAME]` instead.
      Calling `db:rollback:primary` or `db:rollback:animals` will rollback
      the migration for the number of steps specified.
      
      Closes: #38513
      Follow-up to: #34078
      e33075a0
  8. 19 3月, 2020 3 次提交
  9. 18 3月, 2020 1 次提交
    • A
      Use non-exist enum string to get unrelated record in My SQL · 93b8c24f
      ak 提交于
      This behaviour is in
      rails/activerecord/lib/active_record/enum.rb #serialize(value) line no 143
      if value is not present in mapping we are sending the value back ,
      which in mysql returns unrelated record.
      
      I have changed to return nil is value is not present in mapping
      
      Implemented code review changes
      
      Improved test case coverage
      
      [ci skip] - cosmetic changes for better readibility of change log
      Signed-off-by: Nak <atulkanswal@gmail.com>
      93b8c24f
  10. 28 2月, 2020 2 次提交
  11. 27 2月, 2020 1 次提交
  12. 25 2月, 2020 4 次提交
    • R
      Fixup CHANGELOGs [ci skip] · 1d3eb7be
      Ryuta Kamizono 提交于
      1d3eb7be
    • E
      Add support for horizontal sharding · 384e7d13
      eileencodes 提交于
      Applications can now connect to multiple shards and switch between
      their shards in an application. Note that the shard swapping is
      still a manual process as this change does not include an API for
      automatic shard swapping.
      
      Usage:
      
      Given the following configuration:
      
      ```yaml
      production:
        primary:
          database: my_database
        primary_shard_one:
          database: my_database_shard_one
      ```
      
      Connect to multiple shards:
      
      ```ruby
      class ApplicationRecord < ActiveRecord::Base
        self.abstract_class = true
      
        connects_to shards: {
          default: { writing: :primary },
          shard_one: { writing: :primary_shard_one }
        }
      ```
      
      Swap between shards in your controller / model code:
      
      ```ruby
        ActiveRecord::Base.connected_to(shard: :shard_one) do
          # Read from shard one
        end
      ```
      
      The horizontal sharding API also supports read replicas. See
      guides for more details.
      
      This PR also moves some no-doc'd methods into the private namespace as
      they were unnecessarily public. We've updated some error messages and
      documentation.
      Co-authored-by: NJohn Crepezzi <john.crepezzi@gmail.com>
      384e7d13
    • E
      Deprecate `spec_name` and use `name` for configurations · 79ce7d9a
      eileencodes 提交于
      I have so. many. regrets. about using `spec_name` for database
      configurations and now I'm finally putting this mistake to an end.
      
      Back when I started multi-db work I assumed that eventually
      `connection_specification_name` (sometimes called `spec_name`) and
      `spec_name` for configurations would one day be the same thing. After
      2 years I no longer believe they will ever be the same thing.
      
      This PR deprecates `spec_name` on database configurations in favor of
      `name`. It's the same behavior, just a better name, or at least a
      less confusing name.
      
      `connection_specification_name` refers to the parent class name (ie
      ActiveRecord::Base, AnimalsBase, etc) that holds the connection for it's
      models. In some places like ConnectionHandler it shortens this to
      `spec_name`, hence the major confusion.
      
      Recently I've been working with some new folks on database stuff and
      connection management and realize how confusing it was to explain that
      `db_config.spec_name` was not `spec_name` and
      `connection_specification_name`. Worse than that one is a symbole while
      the other is a class name. This was made even more complicated by the
      fact that `ActiveRecord::Base` used `primary` as the
      `connection_specification_name` until #38190.
      
      After spending 2 years with connection management I don't believe that
      we can ever use the symbols from the database configs as a way to
      connect the database without the class name being _somewhere_ because
      a db_config does not know who it's owner class is until it's been
      connected and a model has no idea what db_config belongs to it until
      it's connected. The model is the only way to tie a primary/writer config
      to a replica/reader config. This could change in the future but I don't
      see value in adding a class name to the db_configs before connection or
      telling a model what config belongs to it before connection. That would
      probably break a lot of application assumptions. If we do ever end up in
      that world, we can use name, because tbh `spec_name` and
      `connection_specification_name` were always confusing to me.
      79ce7d9a
    • K
  13. 22 2月, 2020 1 次提交
  14. 21 2月, 2020 1 次提交
  15. 20 2月, 2020 1 次提交
  16. 06 2月, 2020 1 次提交
    • S
      This PR adds support to retrieve partitioned indexes when asking for · db6eb846
      Sebastián Palma 提交于
      indexes in a table.
      
      Currently the pg_class catalog is filtered out to retrieve the indexes in a
      table by its relkind value. Which in versions lower than 11 of PostgreSQL
      is always `i` (lower case). But since version 11, PostgreSQL
      supports partitioned indexes referenced with a relkind value of `I`
      (upper case). This makes any feature within the current code base to exclude those
      partitioned indexes.
      
      The solution proposed is to make use of the `IN` clause to filter those
      relkind values of `i` and/or `I` when retrieving a table indexes.
      db6eb846
  17. 31 1月, 2020 1 次提交
  18. 30 1月, 2020 1 次提交
    • E
      Add support for `if_exists/if_not_exists` on `remove_column/add_column` · 95ed7e78
      eileencodes 提交于
      This PR adds support for `if_exists` on `remove_column` and
      `if_not_exists` on `add_column` to support silently ignoring migrations
      if the remove tries to remove a non-existent column or an add tries to
      add an already existing column.
      
      We (GitHub) have custom monkey-patched support for these features and
      would like to upstream this behavior.
      
      This matches the same behavior that is supported for `create_table` and
      `drop_table`. The behavior for sqlite is different from mysql/postgres
      and sqlite for remove column and that is reflected in the tests.
      95ed7e78
  19. 29 1月, 2020 1 次提交
  20. 24 1月, 2020 2 次提交
    • C
      Fix Active Record changelog [ci skip] · 2d7ff70b
      Carlos Antonio da Silva 提交于
      Follow-up of 1ee4a881.
      2d7ff70b
    • E
      Move advisory lock to it's own connection · 1ee4a881
      eileencodes 提交于
      This PR moves advisory lock to it's own connection instead of
      `ActiveRecord::Base` to fix #37748. As a note the issue is present on
      both mysql and postgres. We don't see it on sqlite3 because sqlite3
      doesn't support advisory locks.
      
      The underlying problem only appears if:
      
      1) the app is using multiple databases, and therefore establishing a new
      connetion in the abstract models
      2) the app has a migration that loads a model (ex `Post.update_all`)
      which causes that new connection to get established.
      
      This is because when Rails runs migrations the default connections are
      established, the lock is taken out on the `ActiveRecord::Base`
      connection. When the migration that calls a model is loaded, a new
      connection will be established and the lock will automatically be
      released.
      
      When Rails goes to release the lock in the ensure block it will find
      that the connection has been closed. Even if the connection wasn't
      closed the lock would no longer exist on that connection.
      
      We originally considered checking if the connection was active, but
      ultimately that would hide that the advisory locks weren't working
      correctly because there'd be no lock to release.
      
      We also considered making the lock more granular - that it only blocked
      on each migration individually instead of all the migrations for that
      connection. This might be the right move going forward, but right now
      multi-db migrations that load models are very broken in Rails 6.0 and
      master.
      
      John and I don't love this fix, it requires a bit too much knowledge of
      internals and how Rails picks up connections. However, it does fix the
      issue, makes the lock more global, and makes the lock more resilient to
      changing connections.
      Co-authored-by: NJohn Crepezzi <john.crepezzi@gmail.com>
      1ee4a881
  21. 23 1月, 2020 1 次提交
    • K
      Allow schema cache path to be defined in the config file · 2c2ff822
      Katrina Owen 提交于
      This updates the database tasks for dumping the Active Record schema cache as
      well as clearing the schema cache file, allowing the path to be defined in the
      database configuration YAML file.
      
      As before, the value can also be defined in an ENV variable, though this would
      not work for a multi-db application. If the value is specified neither in the
      DB config, nor in the ENV, then the path will continue to be derived from the
      DB config spec_name.
      
      Note that in order to make this change cleaner I also moved a bit of logic
      out of a rake task and into the DatabaseTasks class, for symmetry.
      
      We have two rake tasks for the schema cache:
      
          $ rake db:schema:cache:dump
          $ rake db:schema:cache:clear
      
      The cache:dump task was implemented in DatabaseTasks, but the
      cache:clear one was not.
      
      I also added some tests for the behavior that I was changing, since some of
      the code paths weren't tested.
      2c2ff822
  22. 22 1月, 2020 1 次提交
    • E
      Deprecate `#remove_connection` in favor of `#remove_connection_pool` · 7315c91d
      eileencodes 提交于
      Calling `#remove_connection` on the handler is deprecated in favor of
      `#remove_connection_pool`. This change was made to support changing the
      return value from a hash to a `DatabaseConfig` object.
      `#remove_connection` will be removed in 6.2.
      
      NOTE: `#remove_connection` on `ActiveRecord::Base` will also now return
      a `DatabaseConfig` object. We didn't use a deprecation here since
      it's not documented that this method used to return a `Hash`.
      Co-authored-by: NJohn Crepezzi <john.crepezzi@gmail.com>
      7315c91d
  23. 18 1月, 2020 1 次提交
    • E
      Deprecate and replace `#default_hash` and `#[]` · 2a53fe63
      eileencodes 提交于
      Database configurations are now objects almost everywhere, so we don't
      need to fake access to a hash with `#default_hash` or it's alias `#[]`.
      Applications should `configs_for` and pass `env_name` and `spec_name` to
      get the database config object. If you're looking for the default for
      the test environment you can pass `configs_for(env_name: "test", spec_name:
      "primary")`. Change test to developement to get the dev config, etc.
      
      `#default_hash` and `#[]` will be removed in 6.2.
      Co-authored-by: NJohn Crepezzi <john.crepezzi@gmail.com>
      2a53fe63
  24. 14 1月, 2020 1 次提交
  25. 11 1月, 2020 1 次提交
  26. 10 1月, 2020 1 次提交
    • E
      Ensure the reading connection always raises if we try to write · 1c98e6c0
      eileencodes 提交于
      Since test fixtures share connections (due to transactional tests) we
      end up overwriting the reading configuration so Rails doesn't recognize
      it as a replica connection.
      
      This change ensures that if we're using the `reading` role that
      connections will always have prevent writes turned on.
      
      If you need a replica connection that does not block writes, you should
      use a different role name other than `:reading`.
      
      The db selector test and connection handlers test have been updated to
      test for these changes. In the db selector test we don't always have a
      writing handler so I updated test fixtures to return if that's nil.
      
      Lastly one test needed to be updated to use a different handler name due
      to it needing to write to successfully test what it needs to test.
      
      Fixes #37765
      1c98e6c0
  27. 09 1月, 2020 1 次提交
    • E
      Deprecate "primary" as a connection_specification_name for ActiveRecord::Base · b74fbe4e
      eileencodes 提交于
      As multiple databases have evolved it's becoming more and more
      confusing that we have a `connection_specification_name` that defaults
      to "primary" and a `spec_name` on the database objects that defaults to
      "primary" (my bad).
      
      Even more confusing is that we use the class name for all
      non-ActiveRecord::Base abstract classes that establish connections. For
      example connections established on `class MyOtherDatabaseModel <
      ApplicationRecord` will use `"MyOtherDatabaseModel"` as it's connection
      specification name while `ActiveRecord::Base` uses `"primary"`.
      
      This PR deprecates the use of the name `"primary"` as the
      `connection_specification_name` for `ActiveRecord::Base` in favor of
      using `"ActiveRecord::Base"`.
      
      In this PR the following is true:
      
      * If `handler.establish_connection(:primary)` is called, `"primary"`
      will not throw a deprecation warning and can still be used for the
      `connection_specification_name`. This also fixes a bug where using this
      method to establish a connection could accidentally overwrite the actual
      `ActiveRecord::Base` connection IF that connection was not using a
      configuration named `:primary`.
      * Calling `handler.retrieve_connection "primary"` when
      `handler.establish_connection :primary` has never been called will
      return the connection for `ActiveRecord::Base` and throw a deprecation
      warning.
      * Calling `handler.remove_connection "primary"` when
      `handler.establish_connection :primary` has never been called will
      remove the connection for `ActiveRecord::Base` and throw a deprecation
      warning.
      
      See #38179 for details on more motivations for this change.
      Co-authored-by: NJohn Crepezzi <john.crepezzi@gmail.com>
      b74fbe4e
  28. 07 1月, 2020 1 次提交
  29. 03 1月, 2020 1 次提交
    • A
      Enforce fresh ETag header after collection changes · 58b04096
      Aaron Lipman 提交于
      Add ActiveRecord::Relation#cache_key_with_version. This method will be
      used by ActionController::ConditionalGet to ensure that when collection
      cache versioning is enabled, requests using ConditionalGet don't return
      the same ETag header after a collection is modified.
      
      Prior to the introduction of collection cache versioning in
      4f2ac80d, all collection cache keys
      included a version. However, with cache versioning enabled, collection
      cache keys remain constant. In turn, ETag headers remain constant,
      rendering them ineffective.
      
      This commit takes the cache_key_with_version method used for individual
      Active Record objects (from aa8749eb),
      and adds it to collections.
      58b04096
  30. 31 12月, 2019 1 次提交
  31. 21 12月, 2019 1 次提交
  32. 20 12月, 2019 1 次提交
  33. 18 12月, 2019 1 次提交