| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
| |
This is an alternative of #29722, and follow up of #32048.
This does not change the current behavior, but makes it easier to modify
all polymorphic names consistently.
|
|
|
|
|
|
|
|
|
|
|
| |
This is an alternative of #29722, and revert of #29601 and a1fcbd9.
Currently, association creation and normal association finding doesn't
respect `store_full_sti_class`. But eager loading and preloading respect
the setting. This means that if set `store_full_sti_class = false`
(`true` by default), eager loading and preloading can not find
created polymorphic records.
Association creation and finding should work consistently.
|
|
|
|
|
| |
Since #32028, Rails 6 requires Ruby 2.3+.
No longer needed workaround for Ruby 2.2 "private attribute?" warning.
|
|
|
|
|
|
|
| |
With #31615 `type_for_attribute` accepts either
a symbol as well as a string. `has_attribute?` and `attribute_alias`
also accept either. Since these methods call `to_s` on the argument,
we no longer need to do that at the call site.
|
|
|
|
|
|
|
|
|
| |
They are only different by one line of code which doesn't deserve a
hierarchy of 7 classes.
Closes #31079.
[Ryuta Kamizono & Bogdan Gusiev]
|
| |
|
|
|
|
| |
`through_reflection` and `source_reflection` are used only in the class.
|
|
|
|
|
|
|
|
| |
`associated_records_by_owner` had returned customizing result before
calling `associate_records_to_owner` for through association subclasses.
Since #22115, `associate_records_to_owner` is called in the method and
not returned owner and result pairs. Removing the method will reduce
method call and block call nesting.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
This is partially fixed by e617fb57 when through association has already
loaded. Otherwise, second level through association should respect
`preload_scope`.
Fixes #30242.
Closes #30076.
[Ryuta Kamizono & CicholGricenchos]
|
|
|
|
|
|
|
|
|
|
| |
loaded
If through association has already loaded, `source_type` is ignored to
loaded through records. The loaded records should be filtered by
`source_type` in that case.
Fixes #30904.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Benchmark Script:
```
require 'active_record'
require 'benchmark/ips'
ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL'))
ActiveRecord::Migration.verbose = false
ActiveRecord::Schema.define do
create_table :users, force: true do |t|
t.string :name, :email
t.integer :topic_id
t.timestamps null: false
end
create_table :topics, force: true do |t|
t.string :title
t.timestamps null: false
end
end
attributes = {
name: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
email: 'foobar@email.com'
}
class Topic < ActiveRecord::Base
has_many :users
end
class User < ActiveRecord::Base
belongs_to :topic
end
100.times do
User.create!(attributes)
end
users = User.first(50)
Topic.create!(title: 'This is a topic', users: users)
Benchmark.ips do |x|
x.config(time: 10, warmup: 5)
x.report("preload") do
User.includes(:topic).all.to_a
end
end
```
Before:
```
Calculating -------------------------------------
preload 40.000 i/100ms
-------------------------------------------------
preload 407.962 (± 1.5%) i/s - 4.080k
```
After:
```
alculating -------------------------------------
preload 43.000 i/100ms
-------------------------------------------------
preload 427.567 (± 1.6%) i/s - 4.300k
```
|
| |
|
|
|
|
| |
`reflection.join_primary_key`
|
| |
|
|
|
|
|
|
|
|
| |
Since we have `Preloader#preload`, `Preloader::Association#preload` is a
little confusing. And also, since the `preload` method is an abstract
method, it is hard to read where `associated_records_by_owner` is
called. This refactors `Preloader::Association` to ease to read where
`associated_records_by_owner` is called.
|
|
|
|
|
|
|
|
|
| |
given
Related 2b5f5cdd7c1d95716de6a206b6d09ccbb006dc17.
If `reflection.scope` isn't given, `reflection_scope` is always empty
scope. It is unnecessary to merge it.
|
|
|
|
|
|
|
|
|
| |
Related 2b5f5cdd7c1d95716de6a206b6d09ccbb006dc17.
If `through_scope` is empty scope, it is unnecessary to merge it.
And also, comparing relations is a little expensive (will cause
`build_arel`). It is enough to use `empty_scope?` to determine whether
empty scope.
|
|
|
|
| |
`through_scope` is not empty scope if `options[:source_type]` is given.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
`ActiveRecord::Associations::Preloader::Association`.
```
require 'active_record'
require 'benchmark/ips'
ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL'))
ActiveRecord::Migration.verbose = false
ActiveRecord::Schema.define do
create_table :users, force: true do |t|
t.string :name, :email
t.integer :topic_id
t.timestamps null: false
end
create_table :topics, force: true do |t|
t.string :title
t.timestamps null: false
end
end
attributes = {
name: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
email: 'foobar@email.com'
}
class Topic < ActiveRecord::Base
has_many :users
end
class User < ActiveRecord::Base
belongs_to :topic
end
100.times do
User.create!(attributes)
end
users = User.first(50)
100.times do
Topic.create!(title: 'This is a topic', users: users)
end
Benchmark.ips do |x|
x.config(time: 10, warmup: 5)
x.report("preload") do
User.includes(:topic).all.to_a
end
end
```
```
Calculating -------------------------------------
preload 25.000 i/100ms
-------------------------------------------------
preload 251.772 (± 1.2%) i/s - 2.525k
```
```
Calculating -------------------------------------
preload 26.000 i/100ms
-------------------------------------------------
preload 270.392 (± 1.1%) i/s - 2.704k
```
|
|
|
|
|
|
| |
not empty
Because `reflection_scope.values` will create extra new hash.
|
|
|
|
|
| |
If `reflection.scope` isn't given, `reflection_scope` is always
`klass.unscoped`. it is unnecessary to merge it.
|
|
|
|
|
|
|
|
| |
Defined scope treats nil as `all`, but scope in associations isn't so.
If the result of the scope is nil, most features on associations will be
broken. It should treat nil as `all` like defined scope.
Fixes #20823.
|
|
|
|
|
|
|
|
|
|
| |
If `reflection_scope.where_clause` is not empty, `through_scope` should
be joined the source association. But if `values[:references]` in
`reflection_scope` is empty, the source association will not be joined.
It should use `source_reflection.table_name` in that case.
Fixes #22535.
Closes #28763.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Without this fix, preloading `:comments_with_include` will cause the
following error:
```
% bundle exec ruby -w -Itest test/cases/associations/eager_test.rb -n test_eager_with_has_many_through_join_model_with_include
Using sqlite3
Run options: -n test_eager_with_has_many_through_join_model_with_include --seed 1502
E
Error:
EagerAssociationTest#test_eager_with_has_many_through_join_model_with_include:
ActiveRecord::AssociationNotFoundError: Association named 'post' was not found on Post; perhaps you misspelled it?
```
|
|
|
|
|
| |
If `reflection_scope.where_clause` is empty, `scope` isn't changed. So
`scope.eager_loading?` is always false.
|
|
|
|
|
|
| |
Follow up of #29834.
Fixes #30266.
|
|
|
|
|
| |
Since 213796f, array predicate handler supports making binds, so the
preprocess is no longer needed.
|
| |
|
|\
| |
| | |
Make preload query to preparable
|
| |
| |
| |
| |
| |
| |
| | |
Currently preload query cannot be prepared statements even if
`prepared_statements: true` due to array handler in predicate builder
doesn't support making bind params. This makes preload query to
preparable by don't passing array value if possible.
|
|/ |
|
| |
|
|
|
|
| |
These are no longer used since b98668decb9712f26118de57623fd15d7d28646d.
|
|
|
|
|
| |
This reverts commit 3420a14590c0e6915d8b6c242887f74adb4120f9, reversing
changes made to afb66a5a598ce4ac74ad84b125a5abf046dcf5aa.
|
| |
|
|\
| |
| | |
Prevent extra `through_scope`
|
| |
| |
| |
| | |
We can reuse `through_scope` for `reset_association`.
|
|/ |
|
|
|
|
| |
Since through association is always loaded by `preloader.preload`.
|
| |
|
|\
| |
| | |
Remove unnecessary `query_scope`
|
| | |
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
If a parent association was accessed in an `after_find` or
`after_initialize` callback, it would always end up loading the
association, and then immediately overwriting the association we just
loaded. If this occurred in a way that the parent's `current_scope` was
set to eager load the child, this would result in an infinite loop and
eventually overflow the stack.
For records that are created with `.new`, we have a mechanism to
perform an action before the callbacks are run. I've introduced the same
code path for records created with `instantiate`, and updated all code
which sets inverse instances on newly loaded associations to use this
block instead.
Fixes #26320.
|
|\ \
| |/
|/|
| | |
Preserve readonly flag only for readonly association
|
| |
| |
| |
| | |
Fixes #24093
|
| | |
|
| | |
|
|/ |
|
|\
| |
| |
| |
| | |
Honour joining model order in `has_many :through` associations when
eager loading
|