aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/associations
Commit message (Collapse)AuthorAgeFilesLines
* Provide arguments to RecordNotFoundNikita Misharin2017-11-251-1/+7
|
* Consolidate duplicated `to_ary`/`to_a` definitions in `Relation` and ↵Ryuta Kamizono2017-11-101-4/+6
| | | | `CollectionProxy`
* Remove useless preloader classesRyuta Kamizono2017-11-1010-104/+15
| | | | | | | | | They are only different by one line of code which doesn't deserve a hierarchy of 7 classes. Closes #31079. [Ryuta Kamizono & Bogdan Gusiev]
* Don't expose accessors which are internal used onlyRyuta Kamizono2017-11-082-3/+6
|
* Don't expose internal methods in `Preloader::ThroughAssociation`Ryuta Kamizono2017-11-081-8/+7
| | | | `through_reflection` and `source_reflection` are used only in the class.
* Remove useless `associated_records_by_owner`Ryuta Kamizono2017-11-072-16/+10
| | | | | | | | `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.
* Refactor Preloader CodeBogdan Gusiev2017-11-063-81/+40
|
* Fix preloading polymorphic multi-level through associationRyuta Kamizono2017-11-061-1/+7
| | | | | | | | | | | 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]
* Fix preloading polymorphic association when through association has already ↵Ryuta Kamizono2017-11-061-4/+16
| | | | | | | | | | 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.
* Merge pull request #31005 from shuheiktgw/remove_unnecessary_semicolonsMatthew Draper2017-10-281-1/+1
| | | | Removed unnecessary semicolons
* fix initial countpavel2017-10-271-1/+1
|
* Ensure associations doesn't table name collide with aliased joinsRyuta Kamizono2017-10-241-1/+1
| | | | | | Currently alias tracker only refer a table name, doesn't respect an alias name. Should use `join.left.name` rather than `join.left.table_name`.
* Ensure associations doesn't table name collide with string joinsRyuta Kamizono2017-10-231-4/+6
| | | | | Currently we have no test for alias tracking with string joins. I've add test case for that to catch a future regression.
* [Active Record] require => require_relativeAkira Matsuda2017-10-213-3/+3
| | | | This basically reverts 9d4f79d3d394edb74fa2192e5d9ad7b09ce50c6d
* Remove association(true) references from docs [ci skip]Eugene Kenny2017-10-161-4/+0
| | | | | Passing `true` to force an association to reload its records from the database was deprecated in 5.0 and removed in 5.1.
* Joined tables in association scope doesn't use the same aliases with the ↵Ryuta Kamizono2017-10-093-13/+18
| | | | | | | | | parent relation's aliases Building association scope in join dependency should respect the parent relation's aliases to avoid using the same alias name more than once. Fixes #30681.
* Decouple building `AliasTracker` from `JoinDependency`Ryuta Kamizono2017-10-083-14/+7
| | | | | This is preparation to respect parent relation's alias tracking for fixing #30681.
* Move duplicated code to `delete_or_destroy` in `CollectionAssociation`Ryuta Kamizono2017-10-061-4/+2
|
* Ensure `AliasTracker` respects a custom table nameRyuta Kamizono2017-09-302-2/+2
|
* PERF: Partially recover some performance when preloading.Guo Xiang Tan2017-09-261-9/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 ```
* Remove unused delegation to `reflection.options` in `Preloader::Association`Ryuta Kamizono2017-09-182-4/+1
|
* The name of the key on the associated record is abstracted as ↵Ryuta Kamizono2017-09-184-14/+5
| | | | `reflection.join_primary_key`
* The name of the key on the owner is abstracted as `reflection.join_foreign_key`Ryuta Kamizono2017-09-184-17/+5
|
* Extract `associate_records_to_owner` to refactor `Preloader::Association`Ryuta Kamizono2017-09-183-20/+14
| | | | | | | | 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.
* Remove the code that swapping `scope` and `options`Ryuta Kamizono2017-09-181-5/+0
| | | | `options` is never assigned to `scope` as long as using splat hash.
* Early return if `records.empty?` in `Preloader#preload`Ryuta Kamizono2017-09-181-3/+3
|
* Don't pass `reflection_scope` to `preload_scope` if `reflection.scope` isn't ↵Ryuta Kamizono2017-09-181-1/+3
| | | | | | | | | given Related 2b5f5cdd7c1d95716de6a206b6d09ccbb006dc17. If `reflection.scope` isn't given, `reflection_scope` is always empty scope. It is unnecessary to merge it.
* Return `through_scope` only if the scope is not empty scopeRyuta Kamizono2017-09-181-4/+2
| | | | | | | | | 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.
* Remove useless condition in `reset_association`Ryuta Kamizono2017-09-181-2/+1
| | | | `through_scope` is not empty scope if `options[:source_type]` is given.
* PERF: Incorrect memoization in ↵Guo Xiang Tan2017-09-111-1/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | `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 ```
* Remove unnecessary `join_type` in `AssociationScope`Ryuta Kamizono2017-09-081-5/+1
| | | | | | This method was moved from `JoinHelper` in 0fddc3c1, but it is only used for `table.create_join` in the internal and `Nodes::InnerJoin` is default join klass. So it is not needed to pass it explicitly.
* Don't pass `table` to `last_chain_scope` and `next_chain_scope`Ryuta Kamizono2017-09-071-17/+15
| | | | | | Because `table` is part of `reflection`, don't need to pass it explicitly. And also, naming `alias_name` to `table` is a little confusing. `aliased_table` is preferable than `alias_name`.
* `has_many :through` with unscope should affect to through scopeRyuta Kamizono2017-09-071-21/+14
| | | | | | | | | The order of scope evaluation should be from through scope to the association's own scope. Otherwise the association's scope cannot affect to through scope. Fixes #13677. Closes #28449.
* Don't pass unneeded `reflection` to `add_constraints`Ryuta Kamizono2017-09-051-3/+3
| | | | Because `refl.scope` is the same meaning with `chain_head.scope`.
* Assigning `values` is only necessary when `reflection_scope.where_clause` is ↵Ryuta Kamizono2017-09-051-1/+1
| | | | | | not empty Because `reflection_scope.values` will create extra new hash.
* Don't merge `reflection_scope` if `reflection.scope` isn't givenRyuta Kamizono2017-09-051-1/+1
| | | | | If `reflection.scope` isn't given, `reflection_scope` is always `klass.unscoped`. it is unnecessary to merge it.
* Scope in associations should treat nil as `all`Ryuta Kamizono2017-09-044-5/+7
| | | | | | | | 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.
* Fix preloading through association with custom scopeRyuta Kamizono2017-09-021-1/+6
| | | | | | | | | | 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.
* `values[:includes]` in `reflection_scope` is not compatible with `through_scope`Ryuta Kamizono2017-09-021-1/+6
| | | | | | | | | | | | | | | | | 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? ```
* Don't call `scope.eager_loading?` when `reflection_scope.where_clause` is emptyRyuta Kamizono2017-09-021-10/+10
| | | | | If `reflection_scope.where_clause` is empty, `scope` isn't changed. So `scope.eager_loading?` is always false.
* Merge pull request #30403 from yhirano55/fix_broken_doc_for_active_recordRyuta Kamizono2017-08-267-7/+7
|\ | | | | Fix broken doc for Active Record [ci skip]
| * Fix broken doc for Active Record [ci skip]Yoshiyuki Hirano2017-08-257-7/+7
| |
* | Should work inverse association when eager loadingRyuta Kamizono2017-08-251-3/+3
|/ | | | | | | This regression was caused by caa178c1. The block for `set_inverse_instance` should also be passed to join dependency. Fixes #30402.
* Through scope should not be affected by scopingRyuta Kamizono2017-08-152-12/+2
| | | | | | Follow up of #29834. Fixes #30266.
* Merge pull request #27609 from kamipo/fix_association_primary_keyRafael França2017-08-141-4/+7
|\ | | | | Fix `reflection.association_primary_key` for `has_many` association
| * Fix `reflection.association_primary_key` for `has_many` associationsRyuta Kamizono2017-08-131-4/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | It is incorrect to treat `options[:primary_key]` as `association_primary_key` if `has_many` associations because the `:primary_key` means the column on the owner record, not on the association record. It will break `ids_reader` and `ids_writer`. ```ruby people(:david).essay_ids # => ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'essays.first_name' in 'field list': SELECT `essays`.first_name FROM `essays` WHERE `essays`.`writer_id` = 'David' ``` Fixes #14439.
* | Delegate to `Enumerable#find` for `CollectionProxy`Ryuta Kamizono2017-08-132-17/+14
|/ | | | | Since `Relation` includes `Enumerable`, it is enough to use `super` simply.
* Merge pull request #29720 from gaurish/ar_find_error_message_improvementRafael França2017-08-111-1/+3
|\ | | | | Return Not found Ids in ActiveRecord::NotFound
| * Return Not found Ids in ActiveRecord::NotFoundGaurish Sharma2017-07-291-1/+3
| | | | | | | | | | This builds on top of 15e2da656f41af0124f7577858536f3b65462ad5. now it also returns exact Ids which were not found which will be debugging simple.
* | Specify `table.name` only when `scope.table` and `table` are different (#29058)Ryuta Kamizono2017-08-111-4/+12
| | | | | | Fixes #29045.