Commit Graph

9055 Commits

Author SHA1 Message Date
Eugene Kenny
aed6271d8e Sort results to fix nondeterministic test failures
https://buildkite.com/rails/rails/builds/72395#933504f0-6ce1-4493-9742-f23d9b424aa0/979-990
https://buildkite.com/rails/rails/builds/72398#4448ae3f-71ba-4a6e-8fdb-499e94118b56/979-990
https://buildkite.com/rails/rails/builds/72421#db945faf-4344-40d8-b827-7b242973e243/989-1000
https://buildkite.com/rails/rails/builds/72420#414c9213-6287-4fd8-8c2d-02c0a6dd6f9c/1051-1062
2020-10-30 16:05:55 +00:00
Steve Weber
ba99e6d400 Set inverse during has one autosave if necessary
pair: @rebeldroid12
2020-10-30 15:31:40 +00:00
bogdanvlviv
21889ff550
Add more tests for find_signed/! methods
Related to https://github.com/rails/rails/pull/39404, https://github.com/rails/rails/pull/39542
2020-10-30 12:34:54 +02:00
Eugene Kenny
cdfe8aefa6
Merge pull request #38717 from lukeredpath/fix-polymorphic-reference-index-name
Optimise length of default index name for polymorphic references
2020-10-30 01:03:06 +00:00
Ryuta Kamizono
2a0d495039
Merge pull request #40456 from kamipo/attribute_for_database
Add `attribute_for_database` attribute method
2020-10-30 09:53:18 +09:00
Luke Redpath
e8437a68f6 Optimise length of default index name for polymorphic references
This reduces the possibility of generating index names that are too long
for certain databases (e.g. Postgres which has a 63 character limit) by
naming the index based on the reference name rather than the type and id
column names (the default behaviour of t.index).

This still allows the name to be explicitly specified by passing options.
2020-10-30 00:33:39 +00:00
Ryuta Kamizono
3daf2c7b2d
MySQL: Uniqueness validator now respects default database collation
No longer enforce case sensitive comparison by default.
2020-10-30 00:25:46 +00:00
Rafael Mendonça França
426967c6f5
Remove deprecated methods from ActiveRecord::ConnectionAdapters::DatabaseLimits 2020-10-30 00:25:43 +00:00
Rafael Mendonça França
cbf43df288
Remove deprecated ActiveRecord::ConnectionAdapters::AbstractAdapter#supports_multi_insert? 2020-10-30 00:25:43 +00:00
Rafael Mendonça França
ea32fe3de4
Remove deprecated ActiveRecord::ConnectionAdapters::AbstractAdapter#supports_foreign_keys_in_create? 2020-10-30 00:25:42 +00:00
Rafael Mendonça França
ae7b937cfa
Remove deprecated ActiveRecord::ConnectionAdapters::PostgreSQLAdapter#supports_ranges? 2020-10-30 00:25:41 +00:00
Rafael Mendonça França
b232d019a2
Remove deprecated ActiveRecord::Base#update_attributes and ActiveRecord::Base#update_attributes! 2020-10-30 00:25:40 +00:00
Rafael Mendonça França
43591b43a6
Remove deprecated migrations_path argument in ActiveRecord::ConnectionAdapter::SchemaStatements#assume_migrated_upto_version 2020-10-30 00:25:39 +00:00
Ryuta Kamizono
255a7ef7b0
Implicit scoping does no longer leak scope to class level querying methods
This is second attempt of #32380 and #35186.
2020-10-30 00:25:38 +00:00
Rafael Mendonça França
4692cdda5f
Remove deprecated methods from ActiveRecord::DatabaseConfigurations 2020-10-30 00:25:37 +00:00
Rafael Mendonça França
688a1c9d1d
where.not now generates NAND predicates instead of NOR 2020-10-30 00:25:35 +00:00
Rafael Mendonça França
b6d62491e4
Remove deprecated ActiveRecord::Result#to_hash method 2020-10-30 00:25:33 +00:00
Rafael Mendonça França
317465a4a8
Remove deprecated support for using unsafe raw SQL in ActiveRecord::Relation methods 2020-10-30 00:25:32 +00:00
Eugene Kenny
348d6c624c Share connection pools for non-default shards
Unless `legacy_connection_handling` was set to `false`, only the default
shard's connection pools were shared during transactional tests.
2020-10-29 22:52:23 +00:00
Eugene Kenny
03d5fad310
Merge pull request #40487 from eugeneius/only_replace_existing_pools
Only replace existing pools in transactional tests
2020-10-29 22:36:15 +00:00
Eileen M. Uchitelle
2c327e64f9
Merge pull request #40486 from eileencodes/add-method-to-set-specific-connection
Implement `connecting_to` method
2020-10-29 17:31:02 -04:00
Eugene Kenny
5c562a6351 Only replace existing pools in transactional tests
`setup_shared_connection_pool` replaces reading connection pools with
writing ones, so that replica reads work as they would in production.

If a shard doesn't have a reading connection we should skip it, since
adding one could lead to code that only works in the test environment.
2020-10-29 21:15:15 +00:00
eileencodes
231bcc7cd2
Implement connecting_to method
Sometimes you need to have a different default connection but aren't
calling the connection with a block. An example is booting a console in
`reading` mode. This adds the ability for a script to set a specific
connection on boot while preserving the behavior of `connected_to` for
application code.
2020-10-29 17:13:58 -04:00
Eugene Kenny
00e70666ed
Merge pull request #40368 from eugeneius/shard_test_transactions
Eagerly establish test transactions for shards
2020-10-29 21:11:37 +00:00
Eileen M. Uchitelle
60d5928a27
Merge pull request #40370 from eileencodes/granular-role-and-shard-swapping
Implement granular role and shard swapping
2020-10-29 09:09:24 -04:00
eileencodes
6b110d7528
Don't allow granular swapping for shards in legacy
This is a separate commit because I want it to be easy to revert if we
change our minds. After some discussion I think it is confusing that you
could swap shard but not role granularly in legacy mode. This change
forces users to always either have global swapping until moved off
legacy mode. This will prevent a situation where `AnimalsBase` can
change the shard granularly but the role globally.
2020-10-29 08:58:02 -04:00
John Hawthorn
e1b3cf8dc5
Merge pull request #40042 from leequarella/or-unscope-inverse
Fix: Ensure association target is only set if there is not a foreign key mismatch
2020-10-28 15:18:28 -07:00
eileencodes
31461d8a79
Implement granular role and shard swapping
This change allows for a connection to be swapped on role or shard for a
class. Previously calling `connected_to` would swap all the connections
to a particular role or shard. Granular connection swapping is useful
for swapping one connection to reading while leaving all other
connection classes on writing.

The public methods on connection handler have been updated to behave the
same as they did previously on the different handlers. The difference
however is instead of calling
`ActiveRecord::Base.connection_handlers[:reading].clear_all_connections!`
you now call
`ActiveRecord::Base.connection_handler.clear_all_connections!` which
will clear based on current role set by a `connected_to` block. Outside
the context of a `connected_to` block, `clear_all_connections!` can take
an optional parameter to clear specific connections by role.

The major changes in this PR are:

* We introduced a `legacy_connection_handling` configuration option that
is set to true by default. It will be set to `false` for all new
applications.
* In the new connection handling there will be one only connection
handler. Previously there was a connection handler for each role. Now
the role is stored in the `PoolManager`. In order to maintain backwards
compatibility we introduced a `LegacyPoolManager` to avoid duplicate
conditionals. See diagram in PR body for changes to connection
management.
* `connected_to` will now use a stacked concurrent map to keep track of
the connection for each class. For each opened block the `class`,
`role`, and `shard` will be added to the stack, when the block is exited
the `class`, `role`, `shard` array will be removed from the stack.
* With these changes `ActiveRecord::Base.connected_to` will remain
global. If called all connections in the block will use the `role` and
`shard` that was switched to. If called with a parent class like
`AnimalsRecord.connected_to` only models under `AnimalsRecord` will be
switched and everything else will remain the same.

Examples:

Given an application we have a `User` model that inherits from
`ApplicationRecord` and a `Dog` model that inherits from
`AnimalsRecord`. `AnimalsRecord` and `ApplicationRecord` have writing
and reading connections as well as shard `default`, `one`, and `two`.

```ruby
ActiveRecord::Base.connected_to(role: :reading) do
  User.first # reads from default replica
  Dog.first # reads from default replica

  AnimalsRecord.connected_to(role: :writing, shard: :one) do
    User.first # reads from default replica
    Dog.first # reads from shard one primary
  end

  User.first # reads from default replica
  Dog.first # reads from default replica

  ApplicationRecord.connected_to(role: :writing, shard: :two) do
    User.first # reads from shard two primary
    Dog.first # reads from default replica
  end
end
```

Things this PR does not solve:

* Currently there is no API for swapping more than one but not all
connections. Apps with many primaries may want to swap 3 but not all 10
connections. We plan to build an API for that in a followup PR.
* The middleware remains the same and is using the global switching
methods. Therefore at this time to use this new feature applications
must manually switch connections. We will also address this in a
followup PR.
* The `schema_cache` is currently on the `PoolConfig`. We plan on trying
to move this up to the `PoolManager` or elsewhere later on so each
`PoolConfig` doesn't need to hold a reference to the `schema_cache`.

Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
2020-10-28 15:11:35 -04:00
James Adam
d44b628ad0
Dash comments should match read query regexp
As well as allowing queries of the form

    /* some comment */
    SELECT ...

we should also allow queries of the form

    -- some comment
    SELECT ...

Additionally, I've added tests for both comment forms into the general
adapter test case, along with some additional checks to ensure that the
regexp does not return a false-positive match if the read query
signifier keyword is actually a part of the comment.

This expands on the change already implemented in
12b964c50f108f6668d1af2e22939059a217f28a.
2020-10-28 15:00:29 -04:00
bogdanvlviv
aac3d28b4e
Test find_signed/! on Relation
Want to make sure that those methods work on relation and return
expected result when retation has or doesn't have any records.

Those methods are delegated by
7cb4513466/activerecord/lib/active_record/relation/delegation.rb (L21),
7cb4513466/activerecord/lib/active_record/relation/delegation.rb (L95-L114),
7cb4513466/activerecord/lib/active_record/relation/delegation.rb (L56-L78)
as I understand.

Related to https://github.com/rails/rails/pull/39313
2020-10-27 22:59:31 +02:00
Eugene Kenny
7c67dade05
Merge pull request #40414 from Shopify/handle-frozen-paylaods
Handle frozen payloads in AR::Type::Serialized
2020-10-27 10:41:58 +00:00
Lee Quarella
c6f4656477 Only set the association target if there is no foreign key mismatch
fixes #40018

Prior to this commit, the following test would fail. `book`'s author was
actually being returned as `author_b`. (The same would happen for
`unscope`.)

    def test
      author_a = Author.create!
      author_b = Author.create!

      Book.create(author: author_a)

      book = author_b.books.or(author_a.books).first

      assert_equal book.author, author_a
    end

Co-authored-by: Adam Hess <adamhess1991@gmail.com>
2020-10-26 13:53:08 -04:00
Ryuta Kamizono
1429893b24 Add attribute_for_database attribute method
I've been reported an issue on enum from friends, they want a way to get
mapped value, but currently there is no reliable way to get that value.

If a record is loaded from database, `attribute_before_type_cast` works
for that. but the attribute is changed by user, the attribute method
won't work for that.

```ruby
book = Book.new(status: "published")

# returns "published", but what we really want is 2.
book.status_before_type_cast
```

So I propose to add `attribute_for_database` attribute method, it
consistently returns mapped value for enum.
2020-10-26 18:49:42 +09:00
Ryuta Kamizono
d9129512e9
Merge pull request #40433 from kamipo/annotation_for_inspect_query
Annotation for `Relation#inspect` query
2020-10-25 15:49:55 +09:00
Ryuta Kamizono
92ff708476 Re-enable Layout/SpaceAroundOperators cop
We prefer space around operators, but `Layout/SpaceAroundOperators` cop
was temporarily disabled in #36943 since that cop changed to check
alignment strictly somehow.

In RuboCop 1.0.0, that is fixed by https://github.com/rubocop-hq/rubocop/pull/8906.

Related https://github.com/rails/rails/pull/38034#discussion_r359845661,
https://github.com/rails/rails/pull/39770#discussion_r448829561.
2020-10-23 16:12:15 +09:00
Ryuta Kamizono
6bdbf83d06 Annotation for Relation#inspect query
Related #40415, #40208, #39778, #32810, #30497, #29570.

We had been reported lots of issues about `Relation#inspect` query.

I think that annotation for `Relation#inspect` query makes it easier for
people to understand why the query is being executed.
2020-10-22 18:55:40 +09:00
Ryuta Kamizono
09f364b6f6 Remove redundant begin blocks 2020-10-22 17:11:26 +09:00
Jean Boussier
5936ae291b Handle frozen payloads in AR::Type::Serialized 2020-10-20 09:32:21 +02:00
Guillaume Briday
458fff60ce Add values_at attribute method for active_record 2020-10-19 17:15:02 +01:00
Marcelo Lauxen
5fdc7d385f Fix read_attribute_before_type_cast to consider attribute aliases
Numericality validations for aliased attributes are not able
to get the value of the attribute before type cast because
activerecord was trying to get the value of the attribute based
on attribute alias name and not the original attribute name.

Example of validation which would pass even if a invalid value
would be provided

    class MyModel < ActiveRecord::Base
      validates :aliased_balance, numericality: { greater_than_or_equal_to: 0 }
    end

If we instantiate MyModel like bellow it will be valid because
when numericality validation runs it will not be able to get the
value before type cast, so it uses the type casted value
which will be `0.0` and the validation will match.

    subject = MyModel.new(aliased_balance: "abcd")
    subject.valid?

But if we declare MyModel like this

    class MyModel < ActiveRecord::Base
      validates :balance, numericality: { greater_than_or_equal_to: 0 }
    end

and assign "abcd" value to `balance` when the validations
run the model will be invalid because activerecord will be able
to get the value before type cast.

With this change `read_attribute_before_type_cast` will be able to
get the value before type cast even when the attr_name is an
attribute_alias.
2020-10-18 20:32:47 -03:00
Gannon McGibbon
bd90ed1630
Merge pull request #40379 from dmitry/40378-adds-same-record-on-build
Prevent adding the same record twice on build when using source record in attribute when using has_many_inversing  #40378
2020-10-16 18:10:02 -04:00
John Hawthorn
64b1c81532
Merge pull request #40387 from jhawthorn/exists_on_contradiction
Avoid query from exists? on contradictory relation
2020-10-15 11:06:54 -07:00
John Hawthorn
3b622bc0d6 Avoid query from exists? on contradictory relation
Co-authored-by: Adam Hess <HParker@github.com>
2020-10-14 12:30:10 -07:00
Jean Boussier
d6929e5a09 Handle binary strings in Active Record serialized columns
Serialized attributes stored in BLOB columns will be loaded
with the `ASCII-8BIT` (AKA BINARY) encoding.

So unless the serialized payload is pure ASCII, they need
to have the same internal encoding to be properly compared.

Since the serializer have no way to know how the string will
be stored, it's up to the column type to properly set the
encoding.
2020-10-14 11:57:34 +02:00
Eugene Kenny
55badbba3b Skip PostgreSQL interval tests on other adapters
Also remove an unnecessary magic encoding comment.
2020-10-13 21:08:40 +01:00
dmitry
50e4aaaf25
Prevent adding the same record twice on build when using source record in attribute when using has_many_inversing #40378
Record should be replaced via add_to_target, not added as a separate record to an array.
2020-10-13 19:24:02 +03:00
Eileen M. Uchitelle
2e8ca04906
Merge pull request #40366 from tgxworld/fix_flaky_advisory_lock_test
Fix flaky advisory lock test.
2020-10-13 09:09:22 -04:00
Eileen M. Uchitelle
9660f2a986
Merge pull request #40372 from alexrs/patch-1
Stable sorting for DatabaseConfigurations#find_db_config
2020-10-13 08:51:11 -04:00
Alejandro Rodríguez Salamanca
fae2df5f54 Update database_configurations.rb 2020-10-13 09:43:12 +01:00
Guo Xiang Tan
d2215580d8
Fix flaky advisory lock test.
Random failures due to active connection checking within the
assert_no_changes block.

Failure:
MigrationTest#test_with_advisory_lock_closes_connection [/rails/activerecord/test/cases/migration_test.rb:947]:
--- expected
+++ actual
@@ -1 +1 @@
-["SELECT 1", "SELECT 1"]
+["SELECT 1", "SELECT 1", "SELECT 1"]

This commit scopes the query down further to ensure that the advisory
unlock query is not left in pg_stat_activity which is an indication that
the connection pool was not disconnected.
2020-10-13 09:02:09 +08:00