Commit Graph

9055 Commits

Author SHA1 Message Date
Ryuta Kamizono
930bfb9393 Deprecate inconsistent behavior that merging conditions on the same column
Related to #39250 and #39236.

The purpose of the change here is to unify inconsistent behavior on the
merging.

For now, mergee side condition is replaced by merger side condition only
if both arel nodes are Equality or In clauses.

In other words, if mergee side condition is not Equality or In clauses
(e.g. `between`, `or`, `gt`, `lt`, etc), those conditions will be kept
even on the same column.

This behavior is harder to predict unless people are familiar with the
merging behavior.

Originally I suppose this behavior is just an implementation issue
rather than an intended one, since `unscope` and `rewhere`, which were
introduced later than `merge`, works more consistently.

Since most of the conditions are usually Equality and In clauses, I
don't suppose most people have encountered this merging issue, but I'd
like to deprecate the inconsistent behavior and will completely unify
that to improve a future UX.

```ruby
# Rails 6.1 (IN clause is replaced by merger side equality condition)
Author.where(id: [david.id, mary.id]).merge(Author.where(id: bob)) # => [bob]

# Rails 6.1 (both conflict conditions exists, deprecated)
Author.where(id: david.id..mary.id).merge(Author.where(id: bob)) # => []

# Rails 6.1 with rewhere to migrate to Rails 6.2's behavior
Author.where(id: david.id..mary.id).merge(Author.where(id: bob), rewhere: true) # => [bob]

# Rails 6.2 (same behavior with IN clause, mergee side condition is consistently replaced)
Author.where(id: [david.id, mary.id]).merge(Author.where(id: bob)) # => [bob]
Author.where(id: david.id..mary.id).merge(Author.where(id: bob)) # => [bob]
```
2020-06-07 07:26:26 +09:00
Vipul A M
e07d10d583 Expand on specs of self join and add make doc changes to suggest users to also do foreign_key when doing self join 2020-06-05 01:09:50 +05:30
Ryuta Kamizono
95154c93ee
Merge pull request #39530 from kamipo/clear_attribute_change_as_attribute_method
Promote `clear_attribute_change` as attribute methods
2020-06-04 07:00:23 +09:00
Peter Fry
37f3b4dc05
Do not mark Postgresql MAC address and UUID attributes as changed when the assigned value only varies by case.
Fix Rubocop warnings.

Fix merge conflict error.

Fix merge conflict error.
2020-06-03 15:27:07 -04:00
Ryuta Kamizono
6f1bf2a3dd Promote clear_attribute_change as attribute methods
For now, `increment` with aliased attribute does work, but `increment!`
with aliased attribute does not work, due to `clear_attribute_change` is
not aware of attribute aliases.

We sometimes partially updates specific attributes in dirties, at that
time it relies on `clear_attribute_change` to clear partially updated
attribute dirties. If `clear_attribute_change` is not attribute method
unlike others, we need to resolve attribute aliases manually only for
`clear_attribute_change`, it is a little inconvinient for me.

From another point of view, we have `restore_attributes`,
`restore_attribute!`, `clear_attribute_changes`, and
`clear_attribute_change`. Despite almost similar features
`restore_attribute!` is an attribute method but `clear_attribute_change`
is not.

Given the above, I'd like to promote `clear_attribute_change` as
attribute methods to fix issues caused by the inconsisteny.
2020-06-04 04:17:17 +09:00
Austen Madden
3315cc76e0 Fix issue with expression index in insert_all
Based on the docs which state unique_by option of insert_all can use the
index name if desired, one would expect the method to work normally and
use the `unique_by` option to determine duplicates.

However, there's an issue where the insert_all expects a Set instead
of the string representing the index expression it is given. This causes
an error. Returning the string expression instead of attempting to
format it works perfectly though.
2020-06-03 10:10:01 -04:00
fatkodima
1944a7e74c Add basic support for check constraints to database migrations 2020-06-02 22:11:27 -07:00
Ryuta Kamizono
97b8aeb099 Support attribute aliases for type_for_attribute
Similar with #39496.
2020-06-03 02:42:07 +09:00
Ryuta Kamizono
c53c418e6f has_attribute? should be aware of attribute aliases
Related to #39495.

For now, `read_attribute`, `write_attribute`, `[]`, `[]=` are aware of
attribute aliases, but `has_attribute?` is not. It will easily miss
attribute alias resolution before using `has_attribute?`, it is very
inconvenient.

I think the inconvenience is not intended, so `has_attribute?` should be
aware of attribute aliases like as others for consistency.
2020-06-03 00:59:35 +09:00
Ryuta Kamizono
8504576bcf
Merge pull request #39501 from kamipo/alias_attribute_for_validation
Allow attribute aliases for `validates_uniqueness_of`
2020-06-02 21:16:42 +09:00
Ryuta Kamizono
4e206f9830
Merge pull request #39495 from kamipo/timestamp_aliases
Allow attribute aliases for timestamp magic columns
2020-06-01 22:51:09 +09:00
Ryuta Kamizono
7ae406a810 Allow attribute aliases for validates_uniqueness_of
For now, the target attribute allows attribute aliases, but `:scope`'s
attribute does not, the cause is that the former use
`read_attribute_for_validation`, but the latter does not.

Unfortunately we cannot use `read_attribute_for_validation` in this
case, it intentionally bypass custom attribute getter to allow #7072.

To work both alias and #7072, `read_attribute` should be used to resolve
attribute aliases.
2020-06-01 22:44:39 +09:00
Ryuta Kamizono
abae7fcd5f Allow attribute aliases for timestamp magic columns
For now, timestamp magic columns are only allowed for real physical
columns, it is not a matter for newly created app, but it is harder to
get the usefulness for legacy databases.

The reason that doesn't work is some low-level API does not care about
attribute aliases. I think that uses low-level API without attribute
alias resolution for timestamp attributes is not intended (e.g.
`updated_at_before_type_cast` works, but `has_attribute?("updated_at")`
and `_read_attribute("updated_at")` doesn't work).

I've addressed all missing attribute alias resolution for timestamp
attributes to work that consistently.

Fixes #37554.
2020-06-01 21:29:33 +09:00
bogdanvlviv
69bf870c50
Add ActiveRecord::Base.strict_loading_by_default and ActiveRecord::Base.strict_loading_by_default=.
This will allow to enable/disable strict_loading mode by default for a model.
The configuration's value is inheritable by subclasses, but they can override that value and
it will not impact parent class:

```ruby
class Developer < ApplicationRecord
  self.strict_loading_by_default = true

  has_many :projects
end

dev = Developer.first
dev.projects.first
\# => ActiveRecord::StrictLoadingViolationError Exception: Developer is marked as strict_loading and Project cannot be lazily loaded.
```

What is great about this feature that it could help users to nip N+1 queries in
the bud, especially for fresh applications, by setting
`ActiveRecord::Base.strict_loading_by_default = true` / `config.active_record.strict_loading_by_default = true`.
That is also a great way to prevent new N+1 queries in the existing applications
after all the N+1 queries are eliminated.
(See https://guides.rubyonrails.org/v6.0/active_record_querying.html#eager-loading-associations,
https://github.com/seejohnrun/prelude for details on how to fight against N+1 queries).

Related to https://github.com/rails/rails/pull/37400, https://github.com/rails/rails/pull/38541
2020-06-01 12:25:25 +03:00
Ryuta Kamizono
926b3eab80
Merge pull request #39489 from kamipo/deprecate_passing_ar_object_to_quote
Deprecate passing an Active Record object to `quote`/`type_cast` directly
2020-06-01 18:10:00 +09:00
Ryuta Kamizono
23b4aa505d Fix test_statement_cache_with_find_by failure
Statement cache keys has normalized as a string.
2020-06-01 09:50:01 +09:00
Ryuta Kamizono
df94fdc21e Use statement cache for find_by with aliased attribute
```ruby
class Post < ActiveRecord::Base
  alias_attribute :alias_id, :id
end

Benchmark.ips do |x|
  x.report("find_by alias") do
    Post.find_by(alias_id: 1)
  end
end
```

Before:

```
Warming up --------------------------------------
       find_by alias   419.000  i/100ms
Calculating -------------------------------------
       find_by alias      4.260k (± 3.9%) i/s -     21.369k in   5.023768s
```

After:

```
Warming up --------------------------------------
       find_by alias     1.182k i/100ms
Calculating -------------------------------------
       find_by alias     12.122k (± 4.1%) i/s -     61.464k in   5.080451s
```
2020-06-01 09:36:48 +09:00
Eugene Kenny
dc715dd803
Merge pull request #39490 from bogdanvlviv/doc-srict_loading
Clarify docs about strict loading and add a test case for `strict_loading!`
2020-05-31 10:20:02 +01:00
bogdanvlviv
1ff8479688
Clarify docs about strict loading and add a test case for strict_loading!
This commit does the following:
  - Hides `StrictLoadingScope` on API doc(https://edgeapi.rubyonrails.org/)
  - Documents `ActiveRecord::Base#strict_loading?` and `ActiveRecord::Base#strict_loading!`
    methods.
  - Adds the test case for `ActiveRecord::Base#strict_loading!` since it is
    a public API.
2020-05-31 11:26:51 +03:00
Ryuta Kamizono
7c4ddf6f1c Fix test name typo 2020-05-31 12:56:28 +09:00
Ryuta Kamizono
87886c93dc Deprecate passing an Active Record object to quote/type_cast directly
Follow up to #27962.

#27962 only deprecated `quoted_id`, but still conservatively allowed
passing an Active Record object.

Since the quoting methods on a `connection` are low-level API and
querying API does not rely on that ability, so people should pass casted
value instead of an Active Record object if using the quoting methods
directly.
2020-05-31 12:38:29 +09:00
Ryuta Kamizono
b7c846afaf Reset statement cache for association if table_name is changed
Related to #27953.

All statement caches should be owned by the klass, otherwise cannot be
aware of table_name is changed.

Fixes #36453.
2020-05-29 15:12:18 +09:00
Ryuta Kamizono
01cffc3789 Allow where with through association to be expanded condition 2020-05-29 13:22:07 +09:00
Ryuta Kamizono
97c3a5605b
Merge pull request #39465 from kamipo/support_type_cast_for_grandchild_attribute
Support type casting for grandchild's attributes
2020-05-29 08:53:10 +09:00
Ryuta Kamizono
e6c303d9f8 Allow composed_of conditions to be unscoped
Related to 7d4cc56ef894714b06f1f6868c78c7e65a6c77be.
2020-05-29 06:03:09 +09:00
Ryuta Kamizono
9641d0b2ef Support type casting for grandchild's attributes
Related to #39292.

Fixes #39460.
2020-05-29 04:55:13 +09:00
Andrew White
9bdf6a3535
Merge pull request #39464 from rails/make-signed-id-verifier-secret-lazy
Make signed_id_verifier_secret lazily evaluated
2020-05-28 19:18:05 +01:00
Andrew White
9a97b1d62b
Make signed_id_verifier_secret lazily evaluated
The signed id feature introduced in #39313 can cause loading issues
since it may try to generate a key before the secret key base has
been set. To prevent this wrap the secret initialization in a lambda.
2020-05-28 19:00:41 +01:00
Eileen M. Uchitelle
55f519f5b6
Merge pull request #39453 from dylanahsmith/transaction-return-no-raise
activerecord: No warning for return out of transaction block without writes
2020-05-28 08:32:44 -04:00
Ryuta Kamizono
844106efa9 merge doesn't allow to overwrite partially matching nodes
This makes `merge rewhere: true` follow the original `merge`'s behavior.
2020-05-28 08:32:40 +09:00
Ryuta Kamizono
817389d1dd Make remaining migration options to kwargs 2020-05-28 07:51:47 +09:00
Ryuta Kamizono
b9e5859c6f Make index options to kwargs 2020-05-28 07:48:53 +09:00
Dylan Thacker-Smith
4332613b6d activerecord: No warning for return out of transaction block without writes
It doesn't matter if the transaction is rolled back or committed if it
wasn't written to, so we can avoid warning about a breaking change.
2020-05-27 16:49:01 -04:00
Ryuta Kamizono
787b991c94 rewhere allow to overwrite non-attribute nodes
Follow up to #39415.
2020-05-27 09:20:37 +09:00
Ryuta Kamizono
95e130524d Fix flaky assert queries tests
`assert_no_queries` sometimes fails due to counting implict schema info
load queries, most case that is enough to just ignore it.

https://buildkite.com/rails/rails/builds/69598#321bb1bc-ec67-40cd-813f-68dc7809ddde/1444-1452
2020-05-27 08:52:44 +09:00
Ryuta Kamizono
c4682ead52 Fix "warning: instance variable @klass not initialized"
Follow up to #39404.
2020-05-27 00:25:20 +09:00
Ryuta Kamizono
4f95ff7840 Fix preloading for polymorphic association with custom scope
#39378 has changed to use `build_scope` in `join_scopes`, which rely on
`reflection.klass`, but `reflection.klass` is restricted for polymorphic
association, the klass for the association should be passed explicitly.
2020-05-26 04:07:28 +09:00
Ryuta Kamizono
0571da9593
Merge pull request #39415 from kamipo/merge_rewhere_with_non_attrs
`merge(..., rewhere: true)` should have the ability to overwrite non-attribute nodes
2020-05-25 19:11:29 +09:00
Ryuta Kamizono
8e7080e4cc
Merge pull request #39408 from kamipo/remove_limit_on_enum
Remove unused `limit` on `enum` and `set` columns in MySQL
2020-05-25 19:08:47 +09:00
Ryuta Kamizono
e5953db2f3 merge(..., rewhere: true) should have the ability to overwrite non-attribute nodes
Related to #7380 and #7392.

`merge` allows to overwrite non-attribute nodes by #7392, so
`merge(..., rewhere: true)` should also have the same ability, to
migrate from the half-baked current behavior to entirely consistent new
behavior.
2020-05-25 07:21:32 +09:00
sinsoku
26a60c4f29
Allow relations with different SQL comments in or
An error occurs when you pass a relation with SQL comments to the `or` method.

```ruby
class Post
  scope :active, -> { where(active: true).annotate("active posts") }
end

Post.where("created_at > ?", Time.current.beginning_of_month)
  .or(Post.active)
```

In order to work without `ArgumentError`, it changes the `or` method to ignore
SQL comments in the argument.

Ref: https://github.com/rails/rails/pull/38145#discussion_r363024376
2020-05-24 22:43:10 +09:00
Ryuta Kamizono
42914820d9 Do not use object_id on Active Record object directly
Follow up to #38990.
2020-05-24 11:08:24 +09:00
Ryuta Kamizono
86a9b36706 Remove unused limit on enum and set columns in MySQL
Before #36604, `enum` and `set` columns were incorrectly dumped as a
`string` column.

If an `enum` column is defined as `foo enum('apple','orange')`, it was
dumped as `t.string :foo, limit: 6`, the `limit: 6` is seemed to
restrict invalid string longer than `'orange'`.

But now, `enum` and `set` columns are correctly dumped as `enum` and
`set` columns, the limit as longest element is no longer used.
2020-05-24 09:20:55 +09:00
Ryuta Kamizono
859681ec5b Separate primary key column options from table options
Otherwise we cannot handle the same name options for both column and
table (e.g. `:comment`, `:charset`, `:collation`).
2020-05-24 08:15:39 +09:00
Ryuta Kamizono
3c6be5e502 Default engine ENGINE=InnoDB is no longer dumped to make schema more agnostic
5 years ago, I made dumping full table options at #17569, especially to
dump `ENGINE=InnoDB ROW_FORMAT=DYNAMIC` to use utf8mb4 with large key
prefix.

In that time, omitting the default engine `ENGINE=InnoDB` was not useful
since `ROW_FORMAT=DYNAMIC` always remains as long as using utf8mb4 with
large key prefix.

But now, MySQL 5.7.9 has finally changed the default row format to
DYNAMIC, utf8mb4 with large key prefix can be used without dumping the
default engine and the row format explicitly.

So now is a good time to make the default engine is omitted.

Before:

```ruby
create_table "accounts", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", force: :cascade do |t|
end
```

After:

```ruby
create_table "accounts", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
end
```

To entirely omit `:options` option to make schema agnostic, I've added
`:charset` and `:collation` table options to exclude `CHARSET` and
`COLLATE` from `:options`.

Fixes #26209.
Closes #29472.

See also #33608, #33853, and #34742.
2020-05-24 07:50:26 +09:00
David Heinemeier Hansson
fd8fd4ae76
Add delegated type to Active Record (#39341) 2020-05-23 15:14:40 -07:00
player1
277d637277
Take primay_key in count in ActiveRecord::SignedId (#39404)
Co-authored-by: Anton Topchii <player1@infinitevoid.net>
2020-05-23 14:36:06 -07:00
Ryuta Kamizono
35813645b1
Merge pull request #39358 from kamipo/deprecate_group_by_duplicated_fields
Deprecate aggregations with group by duplicated fields
2020-05-24 03:52:29 +09:00
Ryuta Kamizono
2580b83f42 Deprecate aggregations with group by duplicated fields
We've learned that `merge` causes duplicated multiple values easily, so
if we missed to deduplicate the values, it will cause weird behavior
like #38052, #39171.

I've investigated the deduplication for the values, at least that had
existed since Rails 3.0.

bed9179aa1

Aggregations with group by multiple fields was introduced at Rails 3.1,
but we missed the deduplication for the aggregation result, unlike the
generated SQL.

a5cdf0b9eb

While the investigation, I've found that `annotate` is also missed the
deduplication.

I don't suppose this weird behavior is intended for both.

So I'd like to deprecate the duplicated behavior in Rails 6.1, and will
be deduplicated all multiple values in Rails 6.2.

To migrate to Rails 6.2's behavior, use `uniq!(:group)` to deduplicate
group fields.

```ruby
accounts = Account.group(:firm_id)

# duplicated group fields, deprecated.
accounts.merge(accounts.where.not(credit_limit: nil)).sum(:credit_limit)
# => {
#   [1, 1] => 50,
#   [2, 2] => 60
# }

# use `uniq!(:group)` to deduplicate group fields.
accounts.merge(accounts.where.not(credit_limit: nil)).uniq!(:group).sum(:credit_limit)
# => {
#   1 => 50,
#   2 => 60
# }
```
2020-05-24 03:11:53 +09:00
Ryuta Kamizono
7520516605
Merge pull request #39403 from kamipo/merge_should_not_duplicate_same_clauses
Deduplicate same clauses in `merge`
2020-05-24 02:44:54 +09:00
Ryuta Kamizono
5528a79dc7 Deduplicate same clauses in merge
Related to #39328, #39358.

For now, `merge` cannot override non-equality clauses, so non-equality
clauses will easily be duplicated by `merge`.

This deduplicates redundant same clauses in `merge`.
2020-05-24 02:14:41 +09:00
Ryuta Kamizono
6a617cc61e Fix through association with source/through scope which has joins
If source/through scope references other tables in where/order, we
should explicitly maintain joins in the scope, otherwise association
queries will fail with referenced unknown column.

Fixes #33525.
2020-05-22 04:05:27 +09:00
Ryuta Kamizono
489df7eb28 Fix through association to respect source scope for includes/preload
`reflection.scope` is not aware of all source scopes if the association
is through association.

It should use `reflection.join_scopes` for that.

Fixes #39376.
2020-05-21 07:40:01 +09:00
Ryuta Kamizono
c50170d213 loaded should be aliased to loaded? in collection proxy
Fixes #39088.
2020-05-20 22:25:29 +09:00
Aaron Lipman
cb554457a9 Resolve conflict between counter cache and optimistic locking
Bump an Active Record instance's lock version after updating its counter
cache. This avoids raising an unnecessary ActiveRecord::StaleObjectError
upon subsequent transactions by maintaining parity with the
corresponding database record's lock_version column.
2020-05-19 20:39:41 -04:00
eileencodes
5b5da30bc0
Fix index options for if_not_exists/if_exists
The `index_exists?` method wasn't very specific so when we added the
`if_not_exists` to `add_index` and `if_exists` to `remove_index` there
were a few cases where behavior was unexpected.

For `add_index` if you added a named index and then added a second index
with the same columns, but a different name, that index would not get
added because `index_exists` was looking only at column named and not at
the exact index name. We fixed `add_index` by moving the `index_exists`
check below `add_index_options` and pass `name` directly to
`index_exists` if there is a `if_not_exists` option.

For `remove_index` if you added a named index and then tried to remove
it with a nil column and a explicit name the index would not get removed
because `index_exists` saw a nil column. We fixed this by only doing the
column check in `index_exists` if `column` is present.

Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
2020-05-19 16:19:22 -04:00
Aaron Patterson
e3c7ba4612
Merge pull request #39338 from p8/did-you-mean-for-has-many-through
Add DidYouMean for HasManyThroughAssociationNotFoundError
2020-05-19 08:37:01 -07:00
Petrik
9082364a25 Add DidYouMean for HasManyThroughAssociationNotFoundError
If a has_many :through association isn't found we can suggest similar associations:

```
class Author
  has_many :categorizations, -> { }
  has_many :categories, through: :categorizations
  has_many :categorized_posts, through: :categorizations, source: :post
  has_many :category_post_comments, through: :categories, source: :post_comments

  has_many :nothings, through: :kateggorisatons, class_name: "Category"
end

Author.first.nothings

Could not find the association :kateggorisatons in model Author
Did you mean?  categorizations
               categories
               categorized_posts
               category_post_comments
```
2020-05-19 08:27:08 +02:00
Ryuta Kamizono
4774fa0d26 Test multiple values with blank value 2020-05-19 04:57:00 +09:00
Ryuta Kamizono
cdbce035a5
Merge pull request #39330 from kamipo/fix_merge_not_in
Fix merging NOT IN clause to behave the same as before
2020-05-18 21:48:36 +09:00
Ryuta Kamizono
13a3f62ae8 Fix merging NOT IN clause to behave the same as before
`HomogeneousIn` has changed merging behavior for NOT IN clause from
before. This changes `equality?` to return true only if `type == :in` to
restore the original behavior.
2020-05-18 15:56:44 +09:00
Ryuta Kamizono
fa63e5f03e
Merge pull request #39219 from kamipo/bind_param
Should not substitute binds when `prepared_statements: true`
2020-05-18 15:20:00 +09:00
Ryuta Kamizono
f6fb3271d4 Support merging option :rewhere to allow mergee side condition to be replaced exactly
Related #39236.

`relation.merge` method sometimes replaces mergee side condition, but
sometimes maintain both conditions unless `relation.rewhere` is used.

It is very hard to predict merging result whether mergee side condition
will be replaced or not.

One existing way is to use `relation.rewhere` for merger side relation,
but it is also hard to predict a relation will be used for `merge` in
advance, except one-time relation for `merge`.

To address that issue, I propose to support merging option `:rewhere`,
to allow mergee side condition to be replaced exactly.

That option will allow non-`rewhere` relation behaves as `rewhere`d
relation.

```ruby
david_and_mary = Author.where(id: david.id..mary.id)

# both conflict conditions exists
david_and_mary.merge(Author.where(id: bob)) # => []

# mergee side condition is replaced by rewhere
david_and_mary.merge(Author.rewhere(id: bob)) # => [bob]

# mergee side condition is replaced by rewhere option
david_and_mary.merge(Author.where(id: bob), rewhere: true) # => [bob]
```
2020-05-18 14:36:42 +09:00
Ryuta Kamizono
a095916df1
Merge pull request #39321 from kamipo/fix_update_with_dirty_locking_column
Fix update with dirty locking column to not match latest object accidentally
2020-05-18 11:46:04 +09:00
Ryuta Kamizono
6bd2bb7526 Fix rename column in bulk alter table for PostgreSQL
PostgreSQL doesn't support rename column operation in bulk alter table.

Fixes #39322.
2020-05-18 11:14:29 +09:00
Ryuta Kamizono
fba016c7a3 Fix update with dirty locking column to not match latest object accidentally
Related #32163.

We should not identify an object by dirty value. If do so, accidentally
matches latest object even though it is a stale object.
2020-05-18 09:46:09 +09:00
Ryuta Kamizono
c360644ed9 Do not need explicit handler for InfixOperation's subclasses
Unless explicitly intend to behave it differently from the superclass.
2020-05-18 08:18:55 +09:00
Aaron Patterson
b027288823
Merge pull request #39318 from p8/did-you-mean-for-associations
Use DidYouMean for AssociationNotFoundError
2020-05-17 15:24:13 -07:00
Petrik
3bc7756036 Use DidYouMean for AssociationNotFoundError
If an association isn't found we can suggest matching associations:

```
Post.all.merge!(includes: :monkeys).find(6)

Association named 'monkeys' was not found on Post; perhaps you misspelled it?
Did you mean?  funky_tags
               comments
               images
               skimmers
```
2020-05-17 21:32:19 +02:00
David Heinemeier Hansson
1a3dc42c17
Add signed ids to Active Record (#39313)
Add support for finding records based on signed ids, which are tamper-proof, verified ids that can be set to expire and scoped with a purpose. This is particularly useful for things like password reset or email verification, where you want the bearer of the signed id to be able to interact with the underlying record, but usually only within a certain time period.
2020-05-17 11:19:37 -07:00
Ryuta Kamizono
77f7b2df3a Remove sync_with_transaction_state to simplify code base
This also removes the `if @transaction_state&.finalized?` guard which is
harder to understand optimization introduced at #36049. The guard is
faster enough though, but removing that will make attribute access about
2% ~ 4% faster, and will make code base to ease to maintain.

`sync_with_transaction_state` was introduced at #9068 to address memory
bloat when creating lots of AR objects inside a transaction.

I've found #18638 the same design of this to address memory bloat, but
this differs from #18638 in that it will allocate one `WeakMap` object
only when explicit transaction, no extra allocation for implicit
transaction.

Executable script to reproduce memory bloat:

https://gist.github.com/kamipo/36d869fff81cf878658adc26ee38ea1b
https://github.com/rails/rails/issues/15549#issuecomment-46035848

I can see no memory concern with this.

Co-authored-by: Arthur Neves <arthurnn@gmail.com>
2020-05-17 20:57:32 +09:00
Matthew Draper
58bed97226
Merge pull request #39235 from hayesr/cte_alias_predication
Allow the construction of a CTE from an Arel::Table
2020-05-17 04:13:50 +09:30
Ryuta Kamizono
dec12b5cb7
Merge pull request #39305 from kamipo/fix_eager_load_with_arel_joins
Fix eager load with Arel joins to maintain the original joins order
2020-05-16 18:42:54 +09:00
Ryuta Kamizono
af71a82265
Merge pull request #39297 from kamipo/fix_group_by_order_and_limit_offset
Fix group by count with eager loading + order + limit/offset
2020-05-16 18:42:26 +09:00
Ryuta Kamizono
8f365c5d04 Fix eager load with Arel joins to maintain the original joins order
#38354 is caused by #36304, to fix invalid joins order for through
associations.

Actually passing Arel joins to `joins` is not officially supported
unlike string joins, and also Arel joins could be easily converted to
string joins by `to_sql`. But I'd not intend to break existing apps
without deprecation cycle, so I've changed to mark only implicit joins
as leading joins, to maintain the original joins order for user supplied
Arel joins.

Fixes #38354.
2020-05-16 10:17:11 +09:00
Ryuta Kamizono
5812feffe3 Fix group by count with eager loading + order + limit/offset
`count` is too complex feature in Active Record, it is heavily mangling
select values, so it easily hit the ORDER BY with SELECT DISTINCT
limitation.

35bf86fe83/activerecord/lib/active_record/relation/calculations.rb (L133-L140)
35bf86fe83/activerecord/lib/active_record/relation/calculations.rb (L253-L264)

But at least in the case of group by, select values are always to be
aggregated value and group values, so meaningful order values are
originally limited. So in that case, remaining order values should
be safe as long as meaningful order values are set by people.

Fixes #38936.
2020-05-15 17:16:59 +09:00
Edouard CHIN
db0469bf6f Fix AR::Relation#where_values_hash with HomogeousIn:
- Calling `Blog.where(title: ['foo', 'bar']).where_values_hash` now
  returns an empty hash.
  This is a regression since 72fd0bae59 .

  `Arel::Node::HomogeousIn` isn't a `EqualityNode`, the `WhereClause`
  didn't had a case for this.

  I decide to not make `HomogeousIn` inherit from `EqualityNode`,
  because there is a comment questioning it for `In` 57d926a78a/activerecord/lib/arel/nodes.rb (L31)
  Intead I just modified the `WhereClause` case and implemented
  `right` on the node which is needed by `where_value_hash` 57d926a78a/activerecord/lib/active_record/relation/where_clause.rb (L59)
2020-05-15 01:39:19 +02:00
Ryuta Kamizono
a89d20cfc7 Type cast aggregations values for table name unqalified column in joins tables
Follow up of #39292 and #39259.
2020-05-15 06:36:45 +09:00
Ryuta Kamizono
31062c9d9e
Merge pull request #39292 from kamipo/type_cast_pluck_without_table_name_qualified
Type cast `pluck` values for table name unqalified column in joins tables
2020-05-15 06:07:34 +09:00
Ryuta Kamizono
1b3a0a0388
Merge pull request #39280 from kamipo/bypass_argument_forwording_issue
Allow define scope for Ruby reserved keywords
2020-05-15 05:39:31 +09:00
Ryuta Kamizono
4b5d1e0670 Type cast pluck values for table name unqalified column in joins tables
Follow up to #39264, and fixes demonstrated case in #39290.

If the column has no type caster and the model don't know the attribute,
let's will attempt to lookup cast type from join dependency tree.
2020-05-15 05:16:23 +09:00
Eric Hayes
596469d556 Allow the construction of a CTE from an Arel::Table 2020-05-14 12:07:36 -04:00
Ryuta Kamizono
8589e8c236 Allow define scope for Ruby reserved keywords
For now argument forwarding doesn't allow some keywords like `true` as a
method name.

To bypass the issue, fallback to `define_method` if method names are
Ruby reserved keywords.

https://bugs.ruby-lang.org/issues/16854

```ruby
class Works
  def true(*args)
    puts(*args)
  end
end

Works.new.true 1, 2, 3
# => 1, 2, 3

class WontWork
  def true(...)
    puts(...)
  end
end
```

```
% ruby a.rb
a.rb:12: syntax error, unexpected ..., expecting ')'
  def true(...)
a.rb:13: unexpected ...
a.rb:15: syntax error, unexpected `end', expecting end-of-input
```
2020-05-14 21:39:39 +09:00
Ryuta Kamizono
682274f177 Support native RENAME COLUMN syntax for MySQL
MySQL 8.0.3 (and MariaDB 10.5.2) now supports native RENAME COLUMN
syntax.

https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-3.html#mysqld-8-0-3-sql-syntax
https://mariadb.com/kb/en/alter-table/#rename-column
2020-05-14 21:30:34 +09:00
Ryuta Kamizono
b1ac0f5521 Update supports_rename_index? version for MariaDB
Looks like the CI failure is caused by rename index on a foreign key
constraint.

https://buildkite.com/rails/rails/builds/69099#1b008fd1-1d2f-4c87-934a-8cdfd6e42c67/1022-2096
2020-05-14 20:28:19 +09:00
Ryuta Kamizono
e887fd9a02 Exercise test kwargs for scope name containing space 2020-05-14 18:20:55 +09:00
Ryuta Kamizono
1c3e75bf09
Merge pull request #39268 from kamipo/fix_merging_multiple_left_joins
Fix left joins order when merging multiple left joins from different associations
2020-05-14 06:22:50 +09:00
Ryuta Kamizono
89043b7f7f
Merge pull request #39264 from kamipo/fix_type_cast_pluck
Fix `pluck` to correctly type cast same column names and association columns
2020-05-14 06:22:19 +09:00
Ryuta Kamizono
a9d4d889e3 Casting aggregated value takes attribute type precedence over database type
Follow up to #39255, #39039.

One of the purpose of this was to unify the behavior between the
databases.

Original code was:

```ruby
    type   = result.column_types.fetch(column_alias) do
      type_for(column_name)
    end
```

The code will attempt looking up type from `column_types`, then fallback
to attribute types, so I supposed the code was originally intended to
cast a value by the database types.

But now, most modern clients will already return casted values, and no
longer use `column_types`, except Postgres.
As a result, now most adapter accidentally fallback to attribute types.
Since casted by attribute types sometimes doesn't return numeric values,
I've unified the behavior to use database types consistently in #39039.

But later, I've learned that attribute types have important settings
like time zone aware attributes (#39255), and some existing code relying
on attribute types over database types (#39271).

I've changed all aggregated values are casted by attribute types.

Fixes #39271.
2020-05-14 05:48:48 +09:00
eileencodes
67feba0c82
Only run on SQlite3
I can't for the life of me reproduce the failures occurring on buildkite
but I beleive this is the fix. We need to only run this on sqlite3
because we are using a sqlite3 database.
2020-05-13 16:12:33 -04:00
eileencodes
e9d1c9a2fc
Move and update enlist_fixture_connections test
This moves the previous test into the old test and reuses the connection
that that test establishes rather than requiring we muck with temporary
connection pool.

The change here is more correct than the previous code since we're
establishing new connections we should be checking the newly established
reading and writing connections are the same, not checking against the
existing ActiveRecord::Base.connection.

The test here also most closely emulates a real application using
multiple databases.

Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
2020-05-13 11:24:00 -04:00
Santiago Bartesaghi
d4ebba275e
Fix #39205 ReadOnlyError when on writing connection 2020-05-13 11:23:52 -04:00
Ryuta Kamizono
32a7ba91d9 Fix left joins order when merging multiple left joins from different associations
#38597 is caused by #35864.

To reproduce this issue, at least it is required four different models
and three left joins from different relations.

When merging a relation from different model, new stashed (left) joins
should be placed before existing stashed joins, but #35864 had broken
that expectation if left joins are stashed multiple times.

This fixes that stashed left joins order as expected.

Fixes #38597.
2020-05-13 22:48:48 +09:00
Ryuta Kamizono
71f0df943d Fix pluck to correctly type cast same column names and association columns
That issues are caused by using only the model's cast types on the
relation.
To fix that issues, use the attribute's type caster takes precedence
over the model's cast types on the relation.

Fixes #35232.
Fixes #36042.
Fixes #37484.
2020-05-13 20:24:42 +09:00
Ryuta Kamizono
ed29afcc03 Test to reference through association in where 2020-05-13 18:42:07 +09:00
Ryuta Kamizono
5f59eac239 Fix type casting aggregated values on association's attributes
Follow up of #39255.

Previously aggregation functions only use the model's attribute types on
the relation for type cast, this will be looking up association's
attribute and type caster if a column name is table name qualified.

Fixes #39248.
2020-05-13 11:32:11 +09:00
Eugene Kenny
96a1a2a37c Use binread instead of setting file mode manually
Followup to b31022052a54ef76f347973e23519ba86ffc94ff.
2020-05-13 00:05:32 +01:00
Ryuta Kamizono
5450270782
Merge pull request #39255 from kamipo/fix_min_and_max_on_tz_aware_attributes
Fix `minimum` and `maximum` on time zone aware attributes
2020-05-13 03:51:54 +09:00
eileencodes
6833bf4d10
Remove implementation of unchecked_serialize
Since we're checking `serializable?` in the new `HomogeneousIn`
`serialize` will no longer raise an exception. We implemented
`unchecked_serialize` to avoid raising in these cases, but with some of
our refactoring we no longer need it.

I discovered this while trying to fix a query in our application that
was not properly serializing binary columns. I discovered that in at
least 2 of our active model types we were not calling the correct
serialization. Since `serialize` wasn't aliased to `unchecked_serialize`
in `ActiveModel::Type::Binary` and `ActiveModel::Type::Boolean` (I
didn't check others but pretty sure all the AM Types are broken) the SQL
was being treated as a `String` and not the correct type.

This caused Rails to incorrectly query by string values. This is
problematic for columns storing binary data like our emoji columns at
GitHub. The test added here is an example of how the Binary type was
broken previously. The SQL should be using the hex values, not the
string value of "🥦" or other emoji.

We still have the problem `unchecked_serialize` was supposed to fix -
that `serialize` shouldn't validate data, just convert it. We'll be
fixing that in a followup PR so for now we should use `serialize` so we
know all the values are going through the right serialization for their
SQL.
2020-05-12 13:37:22 -04:00
Ryuta Kamizono
11751b2ea2 Fix minimum and maximum on time zone aware attributes
This is the opposite direction of #39039.

#39111 fixes `minimum` and `maximum` on date columns with type casting
by column type on the database. But column type has no information for
time zone aware attributes, it means that attribute type should always
be precedence over column type. I've realized that fact in the related
issue report #39248.

I've reverted the expectation of #39039, to make time zone aware
attributes works.
2020-05-13 02:26:55 +09:00
Gannon McGibbon
678dd6ab80 Refactor uncastable through reflection test to detect join key overrides
The uncastable through reflection check should be testing for foreign
key type overrides on the join model and not a non-integer type on the
through primary key.
2020-05-12 13:09:43 -04:00
Adam Lassek
3a8eee9117 Add support for PostgreSQL contains and overlaps operators
Per [this discussion][arel-discussion] on the discourse forum, this is
an addition to Arel for supporting `@>` (contains) and `&&` (overlaps)
operators in PostgreSQL. They are useful for GIN-indexed data such as a
`jsonb` or array column.

  [arel-discussion]: https://discuss.rubyonrails.org/t/what-has-happened-to-arel/74383/51
2020-05-11 22:01:37 -05:00
Yasuo Honda
950a453dc3 Address InnerJoinAssociationTest#test_eager_load_with_string_joins failure with mysql2
`ReadOnlyTest#test_field_named_field` performs implicit commit the transaction by `ReadOnlyTest#setup`
because of the MySQL database behavior.

This commit addresses the failure at https://buildkite.com/rails/rails/builds/68962#68213887-1cef-4f76-9c95-aebc8799c806
Here are minimum steps to reproduce:

```ruby
% ARCONN=mysql2 bin/test test/cases/readonly_test.rb test/cases/dirty_test.rb test/cases/associations/inner_join_association_test.rb \
-n "/^(?:ReadOnlyTest#(?:test_has_many_with_through_is_not_implicitly_marked_readonly)|DirtyTest#(?:test_field_named_field)|InnerJoinAssociationTest#(?:test_eager_load_with_string_joins))$/" --seed 50855
Using mysql2
Run options: -n "/^(?:ReadOnlyTest#(?:test_has_many_with_through_is_not_implicitly_marked_readonly)|DirtyTest#(?:test_field_named_field)|InnerJoinAssociationTest#(?:test_eager_load_with_string_joins))$/" --seed 50855

..F

Failure:
InnerJoinAssociationTest#test_eager_load_with_string_joins [/Users/yahonda/src/github.com/rails/rails/activerecord/test/cases/associations/inner_join_association_test.rb:87]:
Expected: 3
  Actual: 4

bin/test test/cases/associations/inner_join_association_test.rb:82

Finished in 0.114674s, 26.1611 runs/s, 26.1611 assertions/s.
3 runs, 3 assertions, 1 failures, 0 errors, 0 skips
```

References:
- "13.3.3 Statements That Cause an Implicit Commit"
https://dev.mysql.com/doc/refman/8.0/en/implicit-commit.html
2020-05-11 08:15:36 +09:00
akinomaeni
cdc1cb50dc Fix incorrectly successful datetime precision tests
datetime with precision was passing assert_no_microsecond_precision
unintentionally, because `/\d\z/` is match to both datetime with
precision and datetime without precision. Fixed that by changing
time and regex to make it easier to grasp with and without precision.

Fix stub_version to consider schema_cache. ref: #35795

Remove failing test for unsupported version of MariaDB. ref: fb6743a
2020-05-10 23:31:38 +09:00
Ryuta Kamizono
157f6a6efe Should not substitute binds when prepared_statements: true
Before IN clause optimization 70ddb8a, Active Record had generated an
SQL with binds when `prepared_statements: true`:

```ruby
# prepared_statements: true
#
#   SELECT `authors`.* FROM `authors` WHERE `authors`.`id` IN (?, ?, ?)
#
# prepared_statements: false
#
#   SELECT `authors`.* FROM `authors` WHERE `authors`.`id` IN (1, 2, 3)
#
Author.where(id: [1, 2, 3]).to_a
```

But now, binds in IN clause is substituted regardless of whether
`prepared_statements: true` or not:

```ruby
# prepared_statements: true
#
#   SELECT `authors`.* FROM `authors` WHERE `authors`.`id`IN (1,2,3)
#
# prepared_statements: false
#
#   SELECT `authors`.* FROM `authors` WHERE `authors`.`id`IN (1,2,3)
#
Author.where(id: [1, 2, 3]).to_a
```

I suppose that is considered as a regression for the context:

> While I would prefer that we fix/avoid the too-many-parameters
problem, but I don't like the idea of globally ditching bind params for
this edge case... we're getting to the point where I'd almost consider
anything that doesn't use a bind to be a bug.

https://github.com/rails/rails/pull/33844#issuecomment-421000003

This makes binds consider whether `prepared_statements: true` or not
(i.e. restore the original behavior as before), but still gain that
optimization when need the substitute binds (`prepared_statements: false`,
`relation.to_sql`). Even when `prepared_statements: true`, it still
much faster than before by optimized (bind node less) binds generation.

```ruby
class Post < ActiveRecord::Base
end

ids = (1..1000).each.map do |n|
  Post.create!.id
end

puts "prepared_statements: #{Post.connection.prepared_statements.inspect}"

Benchmark.ips do |x|
  x.report("where with ids") do
    Post.where(id: ids).to_a
  end
end
```

* Before (200058b0113efc7158432484d71c1a4f1484a4a1)

`prepared_statements: true`:

```
Warming up --------------------------------------
      where with ids     6.000  i/100ms
Calculating -------------------------------------
      where with ids     63.806  (± 7.8%) i/s -    318.000  in   5.015903s
```

`prepared_statements: false`:

```
Warming up --------------------------------------
      where with ids     7.000  i/100ms
Calculating -------------------------------------
      where with ids     73.550  (± 8.2%) i/s -    371.000  in   5.085672s
```

* Now with this change

`prepared_statements: true`:

```
Warming up --------------------------------------
      where with ids     9.000  i/100ms
Calculating -------------------------------------
      where with ids     91.992  (± 7.6%) i/s -    459.000  in   5.020817s
```

`prepared_statements: false`:

```
Warming up --------------------------------------
      where with ids    10.000  i/100ms
Calculating -------------------------------------
      where with ids    104.335  (± 8.6%) i/s -    520.000  in   5.026425s
```
2020-05-10 21:59:27 +09:00
Ryuta Kamizono
11f420478c Support ALGORITHM = INSTANT DDL option for index operations on MySQL
Since MySQL 8.0.12, MySQL supports `ALGORITHM=INSTANT` DDL option.

https://dev.mysql.com/doc/refman/8.0/en/innodb-online-ddl-operations.html#online-ddl-index-operations
2020-05-10 07:22:02 +09:00
Ryuta Kamizono
981299e3d2 Eager generate relation methods if a method is on Kernel
Follow up of #34122.

Relation method call is relying on method_missing, but if `Kernel` has
the same named method (e.g. `open`, etc), it will invoke Kernel's method
since method_missing is not happened.

To prevent that, eager generate relation methods if a method is the same
name on `Kernel`.

Fixes #39195.
2020-05-10 06:14:29 +09:00
Ryuta Kamizono
67b369781e Active Record uses singleton class eval in tests 2020-05-10 03:43:05 +09:00
Ryuta Kamizono
2c1b012ad7 Refactor index creation to use index definition visitor
Current SQL generation code is hard to maintenance, I've found a bug
that create index comment in bulk change table when I'm refactoring
that.
2020-05-10 02:01:15 +09:00
Ryuta Kamizono
fc7eab048b Fix index creation to preserve comment in bulk change table on MySQL
I've found the bug when I'm refactoring index creation code in #39203.
2020-05-10 02:01:15 +09:00
Ryuta Kamizono
47779e75b9 Support kwargs for named scopes
We fixed `generate_relation_method` to address kwargs warnings at
#38038, but I missed generated named scopes also need the same fix.

Test case has picked from #39196.

Co-authored-by: John Hawthorn <john@hawthorn.email>
2020-05-09 06:25:43 +09:00
Ryuta Kamizono
7ce3451927 Add test case for generate_relation_method
Positional hash argument should not be dup-ed.
2020-05-09 02:46:07 +09:00
Ryuta Kamizono
7e96bbc05b remove_foreign_key doesn't care :validate option if database has no feature
Fixes #39170.

#39170 is a regression caused by 362348b to maintain kwargs flag to
address kwargs warnings.
2020-05-08 20:55:04 +09:00
Ryuta Kamizono
82b66fe48e Fix the result of aggregations to maintain duplicated "group by" fields
Actually that result is odd and hard to predictable result to me, but we
should not change the public behavior without deprecation cycle.

I had not intended to break any apps, so I've restored the behavior.

Fixes #39171.
2020-05-07 11:53:01 +09:00
Ryuta Kamizono
b385afc5f6
Merge pull request #39172 from kamipo/allow_unscope_table_qualified_value
Allow `unscope` to be aware of table name qualified values
2020-05-07 11:28:11 +09:00
Rafael França
0f60146c8f
Merge pull request #39169 from jonathanhefner/add-date_formats-inspect
Add DATE_FORMATS[:inspect]
2020-05-06 21:40:15 -04:00
Ryuta Kamizono
5136277f44 Allow unscope to be aware of table name qualified values
It is possible to unscope only the column in the specified table.

```ruby
posts = Post.joins(:comments).group(:"posts.hidden")
posts = posts.where("posts.hidden": false, "comments.hidden": false)

posts.count
# => { false => 10 }

# unscope both hidden columns
posts.unscope(where: :hidden).count
# => { false => 11, true => 1 }

# unscope only comments.hidden column
posts.unscope(where: :"comments.hidden").count
# => { false => 11 }
```

Co-authored-by: Slava Korolev <korolvs@gmail.com>
2020-05-07 10:28:55 +09:00
Eugene Kenny
d22216f262
Merge pull request #39148 from hotatekaoru/add_change_null_for_change_table
Add `change_null` for `change_table`
2020-05-07 01:10:27 +01:00
Jonathan Hefner
2b38bf6857 Add DATE_FORMATS[:inspect]
Follow-up to #39147 and #39168.

By adding a new purpose-specific format, we avoid potential pitfalls
from concatenating format strings.  We also save a String allocation per
Time attribute per inspect.

The new format also includes a time zone offset for more introspective
inspection.
2020-05-06 15:05:02 -05:00
Adam Hess
3812134049 Don't attempt to add a string to a lambda
DATE_FORMATS can be either a format string or a lambda we don't want to attempt to concat them with a string if we are in the lambda case
2020-05-06 11:43:24 -07:00
Ryuta Kamizono
46a22ceaff
Merge pull request #39162 from kamipo/dogfooding_symbol_starts_ends_with
Dogfooding "active_support/core_ext/symbol/starts_ends_with"
2020-05-06 17:19:19 +09:00
Xavier Noria
afabe994e0 Removes require_dependency from the AR test suite
In the AR test suite require_dependency does not make much sense. Just
call vanilla require/load.

Note that in the test that made explicit use of it, there are no
autoload paths, and no constants have been autoloaded. In reality, the
code ended up calling Kernel#load.
2020-05-06 09:01:38 +02:00
Ryuta Kamizono
98a1405f07 Dogfooding "active_support/core_ext/symbol/starts_ends_with"
Any missing thing would be found such like #39159.
2020-05-06 14:19:25 +09:00
Ryuta Kamizono
5cb261af8e Ensure type cast is not evaluated at relation build time
Some apps would expect that type cast is not evaluated at relation build
time consistently.

Context:

b571c4f3f2 (r31015008)
https://github.com/rails/rails/pull/34303

And also this removes extra grouping on IN clause behaved as before.
2020-05-06 12:50:24 +09:00
Jonathan Hefner
c806be33f7 Ensure sqlite3_mem transaction tests run in memory
SQLite3 does not recognize paths as file URIs unless the
`SQLite3::Constants::Open::URI` flag is set.  Therefore, without this
flag, a path like "file::memory:" is interpreted as a filename, causing
a "file::memory:" file to be created and used as the database.  Most
tests in `SQLite3TransactionTest` picked up this flag from
`shared_cache_flags`, but a few did not.  Because those tests were
creating a file, the path was changed in #38620 such that it no longer
pointed to an in-memory database.

This commit restores the database path as "file::memory:" and ensures
the URI flag is set whenever `in_memory_db?` is true.
2020-05-05 19:59:35 -05:00
Ryuta Kamizono
42daf01958
Merge pull request #39156 from bogdan/preloader-duplicate-object-ids
Ensure array passed to preloader has no duplicate records by object_id
2020-05-06 02:48:48 +09:00
Bogdan Gusiev
3d76110f63 Ensure array passed to preloader has no duplicate records by object_id
Fixes #39073
2020-05-05 20:30:13 +03:00
eileencodes
200058b011
Revert "Merge pull request #39022 from kamipo/perf_where_in"
This reverts commit 9817d74f3be72d8e685301bfd0acb6a12b9cdda9, reversing
changes made to d326b029e0d3cd649d80a484ceb5138475d3601d.

Just making this easier to merge our PR in. Otherwise there's tons of
conflicts and our PR is faster.
2020-05-05 12:45:10 -04:00
Ryuta Kamizono
57b4668c11 save and save! doesn't take positional arguments
Some commits adds `**` to address kwargs warnings in Ruby 2.7, but
`save` and `save!` are originally doesn't take positional arguments, so
maintain both `*` and `**` is redundant.

6d68bb5f69
09d7ce7975
51a7422c9f
2020-05-05 16:51:21 +09:00
Ryuta Kamizono
9817d74f3b
Merge pull request #39022 from kamipo/perf_where_in
PERF: Improve performance of where when using an array of values
2020-05-05 12:06:35 +09:00
Ryuta Kamizono
d326b029e0
Merge pull request #39051 from kamipo/more_concise_or_ast
More concise Arel `Or` ast and make `Or` visitor non recursive
2020-05-05 12:05:21 +09:00
Ryuta Kamizono
6187b7138c Fix rewhere to truly overwrite collided where clause by new where clause
```ruby
steve = Person.find_by(name: "Steve")
david = Author.find_by(name: "David")

relation = Essay.where(writer: steve)

# Before
relation.rewhere(writer: david).to_a # => []

# After
relation.rewhere(writer: david).to_a # => [david]
```

For now `rewhere` only works for truly column names, doesn't work for
alias attributes, nested conditions, associations.

To fix that, need to build new where clause first, and then get
attribute names from new where clause.
2020-05-05 11:45:29 +09:00
hotatekaoru
972d18eab5 Add change_null for change_table
To change a NOT NULL constraint `reversible`.

When changing a NOT NULL constraint, we use `ActiveRecord::ConnectionAdapters::SchemaStatements#change` method that is not reversible, so `up` and `down` methods were required. Actually, we can use `change_column_null` method if only one constraint changed, but if we want to change multiple constarints with ALTER QUERY, `up` and `down` methods were required.
2020-05-05 11:32:38 +09:00
Eugene Kenny
3d426492d4 Remove obsolete explain logging test
This is a remnant of the auto-explain feature, which was removed in
d3688e02ca52c0b72d3092e8498da51e06b7fc58.
2020-05-05 02:24:53 +01:00
Eugene Kenny
072a962fa2
Merge pull request #39138 from jonathanhefner/flakey-destroyed_by_association-tests
Fix flakey destroyed_by_association tests
2020-05-05 01:51:09 +01:00
Jonathan Hefner
7f5deeeee6 Fix flakey destroyed_by_association tests
Example failure: https://buildkite.com/rails/rails/builds/68661#84f8790a-fc9e-42ef-a7fb-5bd15a489de8/1002-1012

The failing `destroyed_by_association` tests create an author (a
DestroyByParentAuthor) and a book (a DestroyByParentBook) that belongs
to that author.  If the database already contains books that refer to
that author's ID from previous tests (i.e. tests that disabled
`use_transactional_tests`), then one of those books will be loaded and
destroyed instead of the intended DestroyByParentBook book.

By loading the `:books` fixtures, we ensure the database does not
contain such unexpected books.

Co-authored-by: Eugene Kenny <elkenny@gmail.com>
Co-authored-by: Ryuta Kamizono <kamipo@gmail.com>
2020-05-04 19:26:54 -05:00
akinomaeni
a3f4202cd8 Inspect time attributes with subsec
before
```
p Knot.create
=> #<Knot id: 1, created_at: "2016-05-05 01:29:47">
```

after
```
p Knot.create
=> #<Knot id: 1, created_at: "2016-05-05 01:29:47.116928000">
```
2020-05-05 08:32:20 +09:00
Ryuta Kamizono
ed6da7038a Test actual query and result 2020-05-04 21:55:27 +09:00
Ryuta Kamizono
7d4cc56ef8 Fix rewhere to allow overwriting association queries 2020-05-04 20:05:41 +09:00
Eugene Kenny
8fd418955e Allow associations to be autosaved multiple times
Since 901d62c586c20ab38b0f18f4bd9a4419902768c4, associations can only be
autosaved once: after a record has been saved, `@new_record_before_save`
will always be false. This assumes that records only transition to being
persisted once, but there are two cases where it happens multiple times:
when the transaction that saved the record is rolled back, and when the
persisted record is later duplicated.
2020-05-03 08:55:30 +01:00
Ryuta Kamizono
483330eeea
Merge pull request #39111 from kamipo/fix_min_and_max_on_non_numeric_column
Fix `minimum` and `maximum` on non numeric column
2020-05-02 15:11:34 +09:00
Ryuta Kamizono
767edafc69 Fix minimum and maximum on non numeric column
I supposed all aggregation functions will return numeric result in
#39039, but that assumption was incorrect for `minimum` and `maximum`,
if an aggregated column is non numeric type.

I've restored type casting aggregated result for `minimum` and `maximum`.

Fixes #39110.
2020-05-02 14:39:39 +09:00
Ryuta Kamizono
92360e9ea3 Deprecate passing a column to type_cast
The type information for type casting is entirely separated to type
object, so if anyone does passing a column to `type_cast` in Rails 6,
they are likely doing something wrong. See the comment for more details:

28d815b894/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb (L33-L42)

This also deprecates passing legacy binds (an array of `[column, value]`
which is 4.2 style format) to query methods on connection. That legacy
format was kept for backward compatibility, instead of that, I've
supported casted binds format (an array of casted values), it is easier
to construct binds than existing two binds format.
2020-05-02 07:18:30 +09:00
Ryuta Kamizono
7669dc2196 Support limit(n) and offset(n) nodes in dot output 2020-05-02 07:14:17 +09:00
Ryuta Kamizono
3754088685
Merge pull request #39101 from kamipo/remove_without_transaction_enrollment_callbacks
Remove internal `without_transaction_enrollment` callbacks
2020-05-02 05:26:43 +09:00
Ryuta Kamizono
e54fd4e052
Merge pull request #39097 from kamipo/improve_find_by_sql
Avoid quite useless loop in `find_by_sql`
2020-05-02 05:25:19 +09:00
eileencodes
b74256be5b
Add test for slug to ID with ID is out of range
We were testing the behavior of out of range ID's on where queries but
not when out of range slugs are converted to ID's.
2020-05-01 12:45:29 -04:00
Ryuta Kamizono
75873d8f5f Remove internal without_transaction_enrollment callbacks
I've found the internal `without_transaction_enrollment` callbacks which
have not been newly used over five years, when I tried to work reverting
#9068 (https://github.com/rails/rails/pull/36049#issuecomment-487318060).

I think that we will never make that callbacks public, since the
mechanism of `without_transaction_enrollment` is too implementation
specific, at least before #9068, records in a transaction had enrolled
all into the transaction.

That callbacks was introduced at #18936 to make `touch_later` #19324,
but I think that the internal callbacks is overkill to just make the
`touch_later` only, and invoking the extra callbacks also have a little
overhead even if we haven't used that.

So I think we can remove the internal callbacks for now, until we will
come up with a good use for that callbacks.
2020-05-01 23:32:26 +09:00
Ryuta Kamizono
71e45582b7 Avoid quite useless loop in find_by_sql
`column_types` is empty except PostgreSQL adapter, and
`attribute_types.each_key { |k| column_types.delete k }` is also empty
even if PostgreSQL adapter almost all case, so that code is quite
useless. This improves performance for `find_by_sql` to avoid that
useless loop as much as possible.

```ruby
ActiveRecord::Schema.define do
  create_table :active_storage_blobs do |t|
    t.string   :key,          null: false
    t.string   :filename,     null: false
    t.string   :content_type
    t.text     :metadata
    t.string   :service_name, null: false
    t.bigint   :byte_size,    null: false
    t.string   :checksum,     null: false
    t.datetime :created_at,   null: false

    t.index [ :key ], unique: true
  end
end

class ActiveStorageBlob < ActiveRecord::Base
end

Benchmark.ips do |x|
  x.report("find_by") { ActiveStorageBlob.find_by(id: 1) }
end
```

Before:

```
Warming up --------------------------------------
             find_by     1.256k i/100ms
Calculating -------------------------------------
             find_by     12.595k (± 3.4%) i/s -     64.056k in   5.091599s
```

After:

```
Warming up --------------------------------------
             find_by     1.341k i/100ms
Calculating -------------------------------------
             find_by     13.170k (± 3.5%) i/s -     67.050k in   5.097439s
```

To avoid column types loop for PostgreSQL adapter, this skips returning
additional column types if a column has already been type casted by pg
decoders. Fortunately this fixes #36186 partly for common types.
2020-05-01 18:08:44 +09:00
Ryuta Kamizono
348e142b26 Replace result_as_array by type mapping 2020-05-01 17:02:12 +09:00
Ryuta Kamizono
55ef531576 Fix random CI failure due to non-deterministic order
https://buildkite.com/rails/rails/builds/68559#2decc846-c6b5-46f7-a805-426a8063d36c/1016-1027
2020-05-01 15:00:01 +09:00
Ryuta Kamizono
bc99e4014f Should not rely on the global Arel::Table.engine in the framework
Relying on the `Arel::Table.engine` is convenient if an app have only a
single kind of database, but if not so, the global state is not always
the same with the current connection.
2020-05-01 06:55:46 +09:00
Ryuta Kamizono
ab2d859e6c Deprecate allowed_index_name_length in DatabaseLimits
`allowed_index_name_length` was used for internal temporary operations
in SQLite3, since index name in SQLite3 must be globally unique and
SQLite3 doesn't have ALTER TABLE feature (so it is emulated by creating
temporary table with prefix).

`allowed_index_name_length` was to reserve the margin for the prefix,
but actually SQLite3 doesn't have a limitation for identifier name
length, so the margin has removed at 36901e6.

Now `allowed_index_name_length` is no longer relied on by any adapter,
so I'd like to remove the internal specific method which is no longer
used.
2020-04-30 01:21:54 +09:00
Ryuta Kamizono
c3a2b54bef PERF: Improve performance of where when using an array of values
This is a smaller alternative of performance improvement, without
refactoring type casting mechanism #39009.

This is relatively a smaller change (but about 40% faster than before),
so I think this could be easier reviewed without discuss about
refactoring type casting mechanism.

This just makes `attribute.in(values)` less allocation from an array of
casted nodes to one casted array node.

```ruby
ids = (1..1000).each.map do |n|
  Post.create!.id
end

Benchmark.ips do |x|
  x.report("where with ids") do
    Post.where(id: ids).to_a
  end

  x.report("where with sanitize") do
    Post.where(ActiveRecord::Base.sanitize_sql(["id IN (?)", ids])).to_a
  end

  x.compare!
end
```

Before:

```
Warming up --------------------------------------
      where with ids     7.000  i/100ms
 where with sanitize    13.000  i/100ms

Calculating -------------------------------------
      where with ids     70.661  (± 5.7%) i/s -    357.000  in   5.072771s
 where with sanitize    130.993  (± 7.6%) i/s -    663.000  in   5.096085s

Comparison:
 where with sanitize:      131.0 i/s
      where with ids:       70.7 i/s - 1.85x  slower
```

After:

```
Warming up --------------------------------------
      where with ids    10.000  i/100ms
 where with sanitize    13.000  i/100ms

Calculating -------------------------------------
      where with ids     98.174  (± 7.1%) i/s -    490.000  in   5.012851s
 where with sanitize    132.289  (± 8.3%) i/s -    663.000  in   5.052728s

Comparison:
 where with sanitize:      132.3 i/s
      where with ids:       98.2 i/s - 1.35x  slower
```
2020-04-29 09:10:30 +09:00
Ryuta Kamizono
280d6eb2e1 Refactor Arel node Casted, Quoted, and BindParam
Define `value_for_database` and `value_before_type_cast` methods, and
use those.
2020-04-28 16:26:18 +09:00
Eileen M. Uchitelle
148bb058bc
Merge pull request #38751 from nburns/metadata-table
check for metadata table support
2020-04-27 09:01:51 -04:00
Ryuta Kamizono
3de9669188
Merge pull request #39057 from kamipo/deprecate_in_clause_length
Deprecate `in_clause_length` in `DatabaseLimits`
2020-04-27 15:34:29 +09:00
Ryuta Kamizono
60ff119487 Fix typo 2020-04-27 15:30:00 +09:00
Ryuta Kamizono
c0ca7625ca Deprecate in_clause_length in DatabaseLimits
`in_clause_length` was added at c5a284f to address to Oracle IN clause
length limitation.

Now `in_clause_length` is entirely integrated in Arel visitor since
#35838 and #36074.

Since Oracle visitors are the only code that rely on `in_clause_length`.
so I'd like to remove that from Rails code base, like has removed Oracle
visitors (#38946).
2020-04-27 01:09:09 +09:00
Ryuta Kamizono
7d3bff1fdb More concise Arel Or ast and make Or visitor non recursive
Before this, 1000 `Or` nodes will raise "stack level too deep" due to
visiting too deep Arel ast.

This makes more concise Arel `Or` ast and `Or` visitor non recursive if
`Or` nodes are adjoined, as a result, "stack level too deep" is no
longer raised.

```ruby
class Post < ActiveRecord::Base
end

posts = (0..500).map { |i| Post.where(id: i) }

Benchmark.ips do |x|
  x.report("inject scopes") { posts.inject(&:or).to_sql }
end
```

Before:

```
Warming up --------------------------------------
      where with ids     9.000  i/100ms
Calculating -------------------------------------
      where with ids     96.126  (± 2.1%) i/s -    486.000  in   5.058960s
```

After:

```
Warming up --------------------------------------
       inject scopes    10.000  i/100ms
Calculating -------------------------------------
       inject scopes    101.714  (± 2.9%) i/s -    510.000  in   5.018880s
```

Fixes #39032.
2020-04-26 11:37:01 +09:00
Ryuta Kamizono
a5469f0239
Merge pull request #39046 from kamipo/concise_arel_ast
Improve `WhereClause#ast` to make concise Arel ast
2020-04-26 03:50:31 +09:00
Ryuta Kamizono
e63ab64624
Merge pull request #39039 from kamipo/fix_aggregate_on_custom_type
Fix aggregate functions to return numeric value consistently even on custom attribute type
2020-04-26 03:47:25 +09:00
Abhay Nikam
47b17f2991 Skip test cases for upsert_all on relation if database adapter doesn't support update on duplicate records 2020-04-25 20:32:09 +05:30
Ryuta Kamizono
699b64ab63 Improve WhereClause#ast to make concise Arel ast
If only one Arel node exist, wrapping a node by `And` node is obviously
redundant, make concise Arel ast will improve performance for visiting
the ast (about 20% faster for complex ast case).

```ruby
class Post < ActiveRecord::Base
end

posts = (0..500).map { |i| Post.where(id: i) }

Benchmark.ips do |x|
  x.report("inject scopes") { posts.inject { |res, scope| res.or(scope) }.to_sql }
end
```

Before:

```
Warming up --------------------------------------
      where with ids     8.000  i/100ms
Calculating -------------------------------------
      where with ids     80.416  (± 2.5%) i/s -    408.000  in   5.078118s
```

After:

```
Warming up --------------------------------------
      where with ids     9.000  i/100ms
Calculating -------------------------------------
      where with ids     96.126  (± 2.1%) i/s -    486.000  in   5.058960s
```
2020-04-25 18:46:10 +09:00
Ryuta Kamizono
89e1dd619e Fix aggregate functions to return numeric value consistently even on custom attribute type
Currently, `count` and `average` always returns numeric value, but
`sum`, `maximum`, and `minimum` not always return numeric value if
aggregated on custom attribute type.

I think that inconsistent behavior is surprising:

```ruby
# All adapters except postgresql adapter are affected
# by custom type casting.

Book.group(:status).sum(:status)
# => { "proposed" => "proposed", "published" => nil }
```

That is caused by fallback looking up cast type to `type_for(column)`.
Now all supported adapters can return numeric value without that
fallback, so I think we can remove that, it will also fix aggregate
functions to return numeric value consistently.
2020-04-25 14:16:09 +09:00
Ryuta Kamizono
9bd21b174b Use supports_datetime_with_precision? rather than subsecond_precision_supported? 2020-04-25 02:56:53 +09:00
Ryuta Kamizono
5cec7ce3cb Support bulk insert/upsert on relation to preserve scope values
This allows to work `author.books.insert_all` as expected.

Co-authored-by: Josef Šimánek <josef.simanek@gmail.com>
2020-04-25 01:22:54 +09:00
Ryuta Kamizono
41758964e9 Remove a comment that is not fact in tests
mysql2 gem have type casting mechanism from raw payload to Ruby
primitive object.
2020-04-24 17:05:52 +09:00
Ryuta Kamizono
9b8087af05 Remove unused operand1/operand2 aliases
There is no worth to keep those unused aliases and tests which are
private API.
2020-04-23 19:45:36 +09:00
Flavio Wuensche
712ef53c9a Reload schema after ignored_columns reassignment
reload column_names after ignored_columns assignment

code review: remove unnecessary setup and move up reload_schema_from_cache
2020-04-23 07:50:06 +02:00
Eugene Kenny
a6c27d591f
Merge pull request #38990 from eugeneius/transaction_callbacks_object_id
Use __id__ to dedup records for transactional callbacks
2020-04-20 21:26:43 +01:00
Marla Brizel Zeschin
0fac4559e1
Update ActiveRecord::OrTest#test_or_when_grouping (#38978)
Co-authored-by: Ryuta Kamizono <kamipo@gmail.com>
2020-04-21 01:09:03 +09:00
Islam Taha
c22cad9605 Preserve column comment on renaming column
Update activerecord changelog

Specify DB name in changelog and fix typo
2020-04-20 10:40:55 +02:00
Eugene Kenny
8d3ca97032 Use __id__ to dedup records for transactional callbacks
While not a particularly good idea, it's possible to use `object_id` as
an attribute name, typically by defining a polymorphic association named
`object`. Since 718a32ca745672a977a0d4ae401f61f439767405, transactional
callbacks deduplicate records by their `object_id`, but this causes
incorrect behaviour when the record has an attribute with that name.

Using `__id__` instead makes a naming collision much less likely.
2020-04-19 22:48:55 +01:00
Ryuta Kamizono
2fac5de95b touch_attributes_with_time takes keyword arguments
Follow up to 404e1a0acdf369ce6eaa65d70c6977a56ed8a277.
2020-04-17 18:55:58 +09:00
Eileen M. Uchitelle
130513d039
Merge pull request #38967 from eileencodes/add-if-exists-to-remove-index
Add `if_exists` option to `remove_index`
2020-04-16 13:51:14 -04:00
Nick Burns
81f6a1f87f Apply suggestions from review
Co-Authored-By: Eileen M. Uchitelle <eileencodes@users.noreply.github.com>
2020-04-16 09:00:58 -07:00
eileencodes
36ea1084fb
Add if_exists option to remove_index
This PR allows for passing `if_exists` options to the `remove_index`
method so that we can ignore already removed indexes. This work follows
column `if/if_not_exists` from #38352 and `:if_not_exists` on `add_index`
from #38555.

We've found this useful at GitHub, there are migrations where we don't
want to raise if an index was already removed. This will allow us to
remove a monkey patch on `remove_index`.

I considered raising after the `index_name_for_remove` method is called
but that method will raise if the index doesn't exist before we get to
execute. I have a commit that refactors this but after much
consideration this change is cleaner and more straightforward than other
ways of implementing this.

This change also adds a little extra validation to the `add_index` test.
Fix `nodoc` on edited methods.
2020-04-16 09:40:45 -04:00
Ryuta Kamizono
e93f416abe Fix unscoping association scope on joins not to raise an error
#29589 changed merging scope order to allow to unscope default scopes on
association scope (#29611), but that caused a regression #38811 that
accidentally allow join constraint which is required.

```
% bin/test test/cases/associations/has_many_associations_test.rb -n test_unscopes_the_default_scope_of_associated_model_when_used_with_include
Run options: -n test_unscopes_the_default_scope_of_associated_model_when_used_with_include --seed 32978

# Running:

E

Error:
HasManyAssociationsTest#test_unscopes_the_default_scope_of_associated_model_when_used_with_include:
NoMethodError: undefined method `children' for nil:NilClass
    ~/rails/activerecord/lib/active_record/associations/join_dependency/join_association.rb:39:in `block in join_constraints'
    ~/rails/activerecord/lib/active_record/associations/join_dependency/join_association.rb:30:in `reverse_each'
    ~/rails/activerecord/lib/active_record/associations/join_dependency/join_association.rb:30:in `with_index'
    ~/rails/activerecord/lib/active_record/associations/join_dependency/join_association.rb:30:in `join_constraints'
    ~/rails/activerecord/lib/active_record/associations/join_dependency.rb:171:in `make_constraints'
    ~/rails/activerecord/lib/active_record/associations/join_dependency.rb:196:in `block in walk'
    ~/rails/activerecord/lib/active_record/associations/join_dependency.rb:196:in `each'
    ~/rails/activerecord/lib/active_record/associations/join_dependency.rb:196:in `flat_map'
    ~/rails/activerecord/lib/active_record/associations/join_dependency.rb:196:in `walk'
    ~/rails/activerecord/lib/active_record/associations/join_dependency.rb:90:in `block in join_constraints'
    ~/rails/activerecord/lib/active_record/associations/join_dependency.rb:87:in `each'
    ~/rails/activerecord/lib/active_record/associations/join_dependency.rb:87:in `flat_map'
    ~/rails/activerecord/lib/active_record/associations/join_dependency.rb:87:in `join_constraints'
    ~/rails/activerecord/lib/active_record/relation/query_methods.rb:1226:in `build_join_query'
    ~/rails/activerecord/lib/active_record/relation/query_methods.rb:1211:in `build_joins'
    ~/rails/activerecord/lib/active_record/relation/query_methods.rb:1091:in `build_arel'
    ~/rails/activerecord/lib/active_record/relation/query_methods.rb:1063:in `arel'
    ~/rails/activerecord/lib/active_record/relation/finder_methods.rb:419:in `block in limited_ids_for'
    ~/rails/activerecord/lib/active_record/relation.rb:867:in `skip_query_cache_if_necessary'
    ~/rails/activerecord/lib/active_record/relation/finder_methods.rb:419:in `limited_ids_for'
    ~/rails/activerecord/lib/active_record/relation/finder_methods.rb:398:in `apply_join_dependency'
    ~/rails/activerecord/lib/active_record/relation.rb:839:in `block in exec_queries'
    ~/rails/activerecord/lib/active_record/relation.rb:867:in `skip_query_cache_if_necessary'
    ~/rails/activerecord/lib/active_record/relation.rb:834:in `exec_queries'
    ~/rails/activerecord/lib/active_record/relation.rb:639:in `load'
    ~/rails/activerecord/lib/active_record/relation.rb:250:in `records'
    ~/rails/activerecord/lib/active_record/relation/finder_methods.rb:508:in `find_take'
    ~/rails/activerecord/lib/active_record/relation/finder_methods.rb:98:in `take'
    ~/rails/activerecord/lib/active_record/relation/finder_methods.rb:458:in `find_one'
    ~/rails/activerecord/lib/active_record/relation/finder_methods.rb:442:in `find_with_ids'
    ~/rails/activerecord/lib/active_record/relation/finder_methods.rb:69:in `find'
    ~/rails/activerecord/test/cases/associations/has_many_associations_test.rb:2689:in `block in <class:HasManyAssociationsTest>'

bin/test test/cases/associations/has_many_associations_test.rb:2683
```

Required join constraint should not be allowed to unscoping.

Fixes #38811.
2020-04-16 00:34:41 +09:00
Ryuta Kamizono
a2040ee329 Remove unused Arel visitors in the code base
This removes ibm_db, informix, mssql, oracle, and oracle12 Arel visitors
which are not used in the code base.

Actually oracle and oracle12 visitors are used at oracle-enhanced
adapter, but now I think that those visitors should be in the adapter's
repo like sqlserver adapter and the dedicated Arel visitor
(https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/master/lib/arel/visitors/sqlserver.rb),
otherwise it is hard to find a bug and review PRs for the oracle
visitors (e.g. #35838, #37646), since we don't have knowledge and
environment enough for Oracle.
2020-04-15 18:33:37 +09:00
Rafael França
3053e544f3
Merge pull request #38942 from joshmn/joshmn_fix_has_one_touch
Prevent has_one from touching parent record unless persisted
2020-04-14 12:08:20 -04:00
Ryuta Kamizono
0349dfc4f2
Merge pull request #38945 from alimi/schema-cache-dump-test-path
Update SchemaCacheTest#schema_dump_path
2020-04-15 00:16:20 +09:00
Ryuta Kamizono
99a4620a19
Merge pull request #38923 from kamipo/remove_dead_test_code
Remove dead test code for unsupported adapters
2020-04-15 00:02:34 +09:00
Ali Ibrahim
ffc6b648f4 Update SchemaCacheTest#schema_dump_path
* Use ASSETS_ROOT (defined in activerecord/test/config.rb) to guarantee a
    valid path to schema_dump_5_1.yml.
2020-04-14 10:43:47 -04:00
Josh
ba3ef762fc Prevent has_one from touching parent record unless persisted
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.
2020-04-13 20:16:00 -05:00
Eugene Kenny
887d4e1df5 Test queries with leading comments on all adapters
Followup to b94efe9f1be6f8f9df9f286441c3fdd6b8804714.
2020-04-13 08:25:09 +01:00
Jonathan Hefner
5b28e42f65 Fix random CI fail due to non-deterministic order
Example failure: https://buildkite.com/rails/rails/builds/68187#333e3624-ac0d-4b23-95b9-f068d9901093/1016-1028

These tests expect the 2nd Account fixture (with a NULL `firm_id`) to be
in the first four rows of the result set, but that behavior is not
guaranteed without an `order`.
2020-04-12 00:34:45 -05:00
Ryuta Kamizono
7ff9b334e1 Remove dead test code for unsupported adapters
Related #15137.

Firebird related code is already removed in #15137.

We have two `current_adapter?(:DB2Adapter)` in tests, but the adapter is
no longer maintained (last release is November 15, 2012).

https://rubygems.org/gems/db2

Yet another (latest) DB2 adapter (`IBM_DBAdapter`) might support Rails
5.0.7, but apparently do not work for Rails 5.2.

https://rubygems.org/gems/ibm_db

We have few lines mention about DB2 in the doc, but now there is no
worth for almost all current users.
2020-04-12 03:30:25 +09:00
Ryuta Kamizono
3f32329f08
Merge pull request #38916 from kamipo/fix_scoping_when_create_on_association_relation
Allow extra scoping in callbacks when create on association relation
2020-04-12 03:26:54 +09:00
Kir Shatrov
c822d7f940 Remove dead code in tests 2020-04-11 17:41:40 +01:00
Ryuta Kamizono
f64b5fb942 Allow extra scoping in callbacks when create on association relation
#37523 has a regression that ignore extra scoping in callbacks when
create on association relation.

It should respect `klass.current_scope` even when create on association
relation to allow extra scoping in callbacks.

Fixes #38741.
2020-04-10 16:10:49 +09:00
Eugene Kenny
6517263f99 Remove ActiveRecord::DefineCallbacks module
This module was added in 16ae3db5a5c6a08383b974ae6c96faac5b4a3c81 to
allow `ActiveRecord::AttributeMethods::Dirty` to define callbacks and
still have its `_update_record` method wrapped by the version defined in
`ActiveRecord::Callbacks`, so that updates in `before_update` callbacks
are taken into account for partial writes.

The callbacks that created this circular dependency were removed in
34f075fe5666dcf924606f8af2537b83b7b5139f, so we can move the callback
definitions back to the `Callbacks` module.
2020-04-10 06:46:06 +01:00
eileencodes
c34d147767
Add regression test for enum getter/setter behavior
Testing that when you set a symbol for an enum type, you get a string
back and that when you set a string you also get a string back.
2020-04-07 12:47:45 -04:00
alimi
834f5414c3
Fix EagerLoadPolyAssocsTest setup (#38883)
* Fix EagerLoadPolyAssocsTest setup

  * EagerLoadPolyAssocsTest includes a Remembered module in multiple test
    ActiveRecord classes. The module is supposed to keep track of records
    created for each of the included classes individually, but it collects all
    records for every class. This happens because @@remembered is defined on the
    Remembered module and shared between the ActiveRecord classes.  This only
    becomes an issue for databases (like CockroachDB) that use random primary
    keys instead of sequential ones by default.
  * To fix the bug, we can make the remembered collection name unique per
    ActiveRecord class.

* Update EagerLoadPolyAssocsTest test setup

  * Instead of defining remembered as a class variable, we can define it as an
    instance variable that will be unique to every class that includes the
    Remembered module.
2020-04-07 10:14:17 +09:00
Nick Burns
aee310c1bc add option in database config for metadata table
- adds the option `metadata_table` to a database connection
2020-04-03 11:48:08 -07:00
Prathamesh Sonpatki
7ba08037f8
Add support for if_not_exists to indexes
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]
2020-03-29 10:30:01 -04:00
Eugene Kenny
ddaa24ac70 Sort results to fix nondeterministic test failures
https://buildkite.com/rails/rails/builds/67891#867b2766-7984-4280-90d6-7f0412e2d239/1015-1026
2020-03-29 05:30:25 +01:00
Kasper Timm Hansen
982b14548c
Merge branch 'master' into previously-new-record 2020-03-28 20:04:23 +01:00
eileencodes
f3dfed7d06
Revert "Merge pull request #38737 from ak15/active_record_enum"
This reverts commit f265e0ddb1139a91635b7905aae1be76b22c6db1, reversing
changes made to 08dfa9212df4a6bf332a4c49b7e8a7d876a69331.

Reverted due to surprising behavior for applications. We need to
deprecate this behavior first instead of raising by default.
2020-03-26 13:49:38 -04:00
Alexey Vasiliev
4d0c335cbb Support order DESC for find_each, find_in_batches and in_batches 2020-03-24 12:11:27 -07:00
Joel Blum
858cccffd7 Fixes #38716 insert_all enum values by correctly type casting the attributes
fix insert_all enum test

fix rubocop, change  test to double quotes

Update activerecord/test/cases/insert_all_test.rb

fix inser_all_enum_values test: double quotes and order relation before pluck

Co-Authored-By: Ryuta Kamizono <kamipo@gmail.com>

change insert_all_enum_values test to not skip duplicates so it works across adapters
2020-03-21 16:09:13 +01:00
akinomaeni
900cf77cd3 Fix typo in test name
s/has_many_and_belongs_to_many/has_and_belongs_to_many/
2020-03-21 20:58:56 +09:00
Eugene Kenny
4ffd53f32d Allow Relation#pick to use already loaded results
When called on a loaded relation, `pick` will now use the existing
results instead of making another query, just like `pluck` does.
2020-03-18 20:04:22 +00:00
Dylan Thacker-Smith
31be40d1dc
Deprecate committing a transaction exited with return or throw (#29333)
If a transaction is wrapped in a Timeout.timeout(duration) block, then the
transaction will be committed when the transaction block is exited from the
timeout, since it uses `throw`. Ruby code doesn't have a way to distinguish
between a block being exited from a `return`, `break` or `throw`, so
fixing this problem for the case of `throw` would require a backwards
incompatible change for block exited with `return` or `break`. As such,
the current behaviour so it can be changed in the future.
2020-03-18 12:58:31 -07:00
ak
93b8c24f18 Use non-exist enum string to get unrelated record in My SQL
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: ak <atulkanswal@gmail.com>
2020-03-18 16:37:45 +05:30
eileencodes
166aee88e4
Remove convenience class alias
This convenience class is only used twice in Arel. We can easily write
it out instead.
2020-03-13 13:48:08 -04:00
Rafael França
795140dbc0
Merge pull request #38690 from abhaynikam/38685-add-option-to-disable-sql-color
Disable colorize logging of SQL and reduce unnecessary invocation of sql_color matching
2020-03-12 10:54:30 -04:00
Abhay Nikam
85b5cd344b Disable colorize logging of SQL and reduce unnecessary invokation of sql_color matching
When the `colorize_logging` is disabled,
logs do not colorize the SQL queries.
But the `sql_color` method is always
invoked which due to regex matching results
in slow queries.

This PR fixes #38685 and removes
unnecessary invokation of `sql_color`
method when `colorize_logging` is disabled
2020-03-11 11:06:08 +05:30
Ryuta Kamizono
d5be4f1a46 Always respond to set_server_option since mysql2 0.5.0
https://github.com/brianmario/mysql2/pull/943
https://github.com/rails/rails/pull/37191
2020-03-10 17:20:45 +09:00
eileencodes
095f1bfaa0
Refactor schema migration on connection
This method was jumping through extra hoops to find the name of the
class the connection is stored on when we can get it from the connection
itself. Since we already have the connection we don't need to loop through the
pools.

In addition, this was using the wrong class name. The class name for the
schema migration should come from the connection owner class, not from
the `db_config.name`. In this case, `db_config.name` is the name of the
configuration in the database.yml. Rails uses the class name to lookup
connections, not the db config name, so we should be consistent here.

While working on this I noticed that we were generating an extra schema
migration class for `ActiveRecord::Base`. Since `ActiveRecord::Base` can
and should use the default and we don't want to create a new one for
single db applications, we should skip creating this if the spec name is
`ActiveRecord::Base`. I added an additional test that ensures the class
generation is correct.
2020-03-09 09:59:36 -04:00
eileencodes
7400d195e2
Remove owner_name
We don't actually need this since the only reason it exists is to pass
the owning class name down to the `handler`. This removes a level of
indirection and an unnecessary accessor on db_config. db_config
shouldn't have to know what class owns it, so we can just remove this
and pass it to the handler.

The Symbol case is needed to preserve current behavior. This doesn't
need a changelog because it's changing un-released behavior.

Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
2020-03-07 09:00:43 -05:00
Eugene Kenny
d3599d8aff Use index_by and index_with wherever possible
Using `index_by` or `index_with` is more concise than `each_with_object`
and more performant than `map { ... }.to_h` or `Hash[map { ... }]`.
2020-03-05 01:24:14 +00:00
Eileen M. Uchitelle
c779d527d0
Merge pull request #38636 from eileencodes/refactor-invert_predicate
Refactor invert predicate
2020-03-04 09:30:34 -05:00
eileencodes
27fb356360
Refactor invert predicate
Instead of doing a case statement here we can have each of the objects
respond to `invert`. This means that when adding new objects we don't
need to increase this case statement, it's more object oriented, and
let's be fair, it looks better too.

Aaron and I stumbled upon this while working on some performance
work in Arel.

I removed `random_object` from the invert test because we don't support
random objects. If you pass a random object to Arel, it should raise,
not be inverted.

Co-authored-by: Aaron Patterson <aaron.patterson@gmail.com>
2020-03-04 09:28:51 -05:00
bogdanvlviv
82a136256a
Rename 'db' to 'test/db' in Active Record's tests 2020-03-03 13:31:12 +00:00
bogdanvlviv
22877a9ddd
Add activerecord/db/ to gitignore
After running `bundle exec rake test:sqlite3` and `bundle exec rake test:sqlite3_mem`
on my VM I noticed that it had created untracked files:

```bash
vagrant@ubuntu-bionic:/rails/activerecord$ git status
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        db/
        file::memory:
```

To prevent them from being accidentally committed I put 'file::memory:' to
`activerecord/db/` folder and added the folder to .gitignore
Also, we could consider fixing this by removing `db/` folder in each test that
creates the folder.

It would be great if someone confirms that it happens not only on my VM.
2020-03-02 14:23:46 +00:00
Abhay Nikam
339d1cdc27 Fixes TypeError raised for parameter filter if the json data has key as integer 2020-02-28 17:27:58 +09:00
Ryuta Kamizono
7205b9f4a6
Merge pull request #38583 from kamipo/fix_unscope_with_arel_sql
Fix `unscope` when an `eq` node which has no arel attribute
2020-02-28 03:58:11 +09:00
Ryuta Kamizono
9698c1bff7 Fix unscope when an eq node which has no arel attribute
Current code expect an `eq` node has one arel attribute at least, but an
`eq` node may have no arel attribute (e.g. `Arel.sql("...").eq(...)`).

In that case `unscope` will raise `NoMethodError`:

```
% bundle exec ruby -w -Itest test/cases/relations_test.rb -n test_unscope_with_arel_sql
Using sqlite3
Run options: -n test_unscope_with_arel_sql --seed 4477

# Running:

E

Error:
RelationTest#test_unscope_with_arel_sql:
NoMethodError: undefined method `name' for #<Arel::Nodes::Quoted:0x00007f9938e55960>
    /Users/kamipo/src/github.com/rails/rails/activerecord/lib/active_record/relation/where_clause.rb:157:in `block (2 levels) in except_predicates'
    /Users/kamipo/src/github.com/rails/rails/activerecord/lib/arel.rb:57:in `fetch_attribute'
    /Users/kamipo/src/github.com/rails/rails/activerecord/lib/active_record/relation/where_clause.rb:157:in `block in except_predicates'
    /Users/kamipo/src/github.com/rails/rails/activerecord/lib/active_record/relation/where_clause.rb:156:in `reject'
    /Users/kamipo/src/github.com/rails/rails/activerecord/lib/active_record/relation/where_clause.rb:156:in `except_predicates'
    /Users/kamipo/src/github.com/rails/rails/activerecord/lib/active_record/relation/where_clause.rb:31:in `except'
    /Users/kamipo/src/github.com/rails/rails/activerecord/lib/active_record/relation/query_methods.rb:487:in `block (2 levels) in unscope!'
    /Users/kamipo/src/github.com/rails/rails/activerecord/lib/active_record/relation/query_methods.rb:481:in `each'
    /Users/kamipo/src/github.com/rails/rails/activerecord/lib/active_record/relation/query_methods.rb:481:in `block in unscope!'
    /Users/kamipo/src/github.com/rails/rails/activerecord/lib/active_record/relation/query_methods.rb:471:in `each'
    /Users/kamipo/src/github.com/rails/rails/activerecord/lib/active_record/relation/query_methods.rb:471:in `unscope!'
    /Users/kamipo/src/github.com/rails/rails/activerecord/lib/active_record/relation/query_methods.rb:464:in `unscope'
    test/cases/relations_test.rb:2062:in `test_unscope_with_arel_sql'
```

We should check for both `value.left` and `value.right` those are arel
attribute or not.
2020-02-27 18:43:56 +09:00
eileencodes
b7b26fabee Disallow calling connected_to on subclasses of ActiveRecord::Base
Behavior has not changed here but the previous API could be
misleading to people who thought it would switch connections for only
that class. `connected_to` switches the context from which we are
getting connections, not the connections themselves.

Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
2020-02-26 16:07:55 -05:00
Ryuta Kamizono
ab0df2f6b0 Fix deprecation warnings in connection_handlers_sharding_db_test.rb 2020-02-25 14:34:34 +09:00
Ryuta Kamizono
8a72d42bcc reset_column_information does not reset @predicate_builder 2020-02-25 13:48:19 +09:00
Katrina Owen
ffc3af63e0
Support gzip for schema cache
This adds gzip support for both the YAML and the Marshal serialization
strategies.

Particularly large schema caches can become a problem when deploying to
Kubernetes, as there is currently a 1*1024*1024 byte limit for the
ConfigMap. For large databases, the schema cache can exceed this limit.
2020-02-24 14:56:13 -07:00
eileencodes
384e7d139e
Add support for horizontal sharding
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: John Crepezzi <john.crepezzi@gmail.com>
2020-02-24 14:05:55 -05:00
eileencodes
79ce7d9af6
Deprecate spec_name and use name for configurations
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.
2020-02-24 13:27:07 -05:00
Kevin Deisz
b8ae104318
Support strict_loading on association declarations 2020-02-21 13:11:24 -05:00
Eugene Kenny
9e40348645 Enable HashTransformKeys and HashTransformValues cops
Followup to 88fe76e69328d38942130e16fb65f4aa1b5d1a6b.

These are new in RuboCop 0.80.0, and enforce a style we already prefer
for performance reasons (see df81f2e5f5df46c9c1db27530bbd301b6e23c4a7).
2020-02-20 22:37:32 +00:00
Gannon McGibbon
89d1d39c8f
Merge pull request #38394 from javiyu/fix-double-object-on-inverse-creation
Fix: on accessing the parent record before creation with has_many_inv…
2020-02-20 15:53:21 -05:00
eileencodes
dbb92f8a77
Add strict_loading mode to prevent lazy loading
Add `#strict_loading` to any record to prevent lazy loading of associations.
`strict_loading` will cascade down from the parent record to all the
associations to help you catch any places where you may want to use
`preload` instead of lazy loading. This is useful for preventing N+1's.

Co-authored-by: Aaron Patterson <aaron.patterson@gmail.com>
2020-02-20 08:32:48 -05:00
Javier Jimenez
3f86157732 Fix: on accessing the parent record before creation with has_many_inversing adds two records to association 2020-02-20 09:26:47 +01:00
Eugene Kenny
4f92aa6741 Copy argument in AttributeAssignment#attributes=
Before df186bd16f0d4a798e626297277fc6b490c1419e, `assign_attributes` and
`attributes=` were both defined in Active Model and both made a copy of
their argument. Now `assign_attributes` is overridden in Active Record
and the copy happens there instead, but `attributes=` isn't overridden.

This meant that assigning nested or multi-parameters via `attributes=`
would mutate the argument, which the copying was meant to prevent.
2020-02-16 23:40:03 +00:00
Rafael França
40c7c5e991
Merge pull request #38432 from kytrinyx/schema-cache-serialization-strategy-2
Expose Marshal as a legit SchemaCache serialization strategy
2020-02-13 14:57:41 -05:00
Katrina Owen
9a356fcd42
Support marshal as a schema cache serialization strategy 2020-02-13 11:59:35 -07:00
Katrina Owen
b71c1cdddd
Push schema cache loading into schema cache class 2020-02-13 11:59:11 -07:00
Ryuta Kamizono
ac7eee44f0
Merge pull request #38438 from kamipo/fix_association_query_with_custom_handler
Registered predicate handler should be used for association queries
2020-02-13 11:47:53 +09:00
Ryuta Kamizono
f330f37c7a Registered predicate handler should be used for association queries
This issue is caused due to association queries uses newly created fresh
onetime predicate builder, it doesn't realize registered predicate
handler. To fix the issue, dup the predicate builder for the klass
instead of newly creating.

Fixes #38239.
2020-02-12 17:09:20 +09:00
Ryuta Kamizono
a8398e0e5b OID type should accept a value range of unsigned integers
Related #38425.
2020-02-12 16:42:33 +09:00
Katrina Owen
0a51442722
Push db schema cache dump into schema cache class 2020-02-11 15:11:46 -07:00
Kurtis Rainbolt-Greene
ef7599fe91
Extract internal ActiveSupport::ConfigurationFile object
Rails has a number of places where a YAML configuration file is read,
then ERB is evaluated and finally the YAML is parsed.

This consolidates that into one common class.

Co-authored-by: Kasper Timm Hansen <kaspth@gmail.com>
2020-02-10 02:50:12 +01:00
Kasper Timm Hansen
534fc4f0c8
Merge pull request #37627
Closes #37627
2020-02-10 01:00:30 +01:00
Bob Lail
3a8668bd73
Touch updated_at when upsert_all modifies a record
- When a user passes `updated_at` to `upsert_all`, the given value is used.
- When a user omits `updated_at`, `upsert_all` touches the timestamp if (but only if) any upserted values differ.

Preserve Rails' ability to generate intelligent cache keys for ActiveRecord when using `upsert_all` frequently to sync imported data.
2020-02-10 01:00:03 +01:00
Erik Berlin
fdaa31896c Fix grammar and diction of NOR conditions warning message 2020-02-06 13:24:05 -08:00
Sebastián Palma
db6eb846eb This PR adds support to retrieve partitioned indexes when asking for
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.
2020-02-06 07:36:44 +02:00
Ryuta Kamizono
6a80902663 Fix foreign_key_exists? in change_table to allow keyword arguments 2020-02-05 09:03:15 +09:00
Ryuta Kamizono
db8e957c84 Fix non-condition elsif 2020-02-01 09:02:45 +09:00
eileencodes
95ed7e7809
Add support for if_exists/if_not_exists on remove_column/add_column
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.
2020-01-30 09:50:44 -05:00
Ryuta Kamizono
1f08fec27e Generalize FrozenError on write attribute 2020-01-29 11:23:41 +09:00
Ryuta Kamizono
5aae2b2783 Simplify RUBY_VERSION checking in tests 2020-01-29 09:31:00 +09:00
Ryuta Kamizono
df9b61f38f Fix CI failure on Ruby master
Ref https://github.com/ruby/ruby/pull/2857.
2020-01-29 09:22:25 +09:00
Eileen M. Uchitelle
1795a2f5e8
Merge pull request #38339 from eileencodes/force-connected_to-to-load-the-relation
Force connected_to to load the records if it's a Relation
2020-01-28 14:40:57 -05:00