aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/associations
Commit message (Collapse)AuthorAgeFilesLines
* Merge pull request #35247 from bogdan/fix-source-reflection-reset-codeRyuta Kamizono2019-02-202-21/+10
|\ | | | | Fix reset of the source association when through association is loaded
| * Fix reset of the source association when through association is loadedBogdan Gusiev2019-02-202-21/+10
| | | | | | | | | | | | | | | | | | The special case happens when through association has a custom scope that is applied to the source association when loading. In this case, the soucre association would need to be reset after main association is loaded. See tests. The special case exists when a through association has
* | Fix eager loading polymorphic association with mixed table conditionsRyuta Kamizono2019-02-181-6/+11
| | | | | | | | | | | | This fixes a bug that the `foreign_key` and the `foreign_type` are separated as different table conditions if a polymorphic association has a scope that joins another tables.
* | Revert "Merge pull request #35127 from bogdan/counter-cache-loading"Ryuta Kamizono2019-02-132-11/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | This reverts commit eec3e28a1abf75676dcee58308ee5721bb53c325, reversing changes made to 5588fb4802328a2183f4a55c36d6703ee435f85c. Reason: Marking as loaded without actual loading is too greedy optimization. See more context #35239. Closes #35239. [Edouard CHIN & Ryuta Kamizono]
* | Merge pull request #35196 from gmcgibbon/clarify_collection_proxy_docsGannon McGibbon2019-02-112-11/+25
|\ \ | | | | | | Clarify collection proxy docs
| * | Clarify collection proxy docsGannon McGibbon2019-02-082-11/+25
| |/ | | | | | | | | | | | | | | | | The docs for `ActiveRecord::Associations::CollectionProxy` describe `ActiveRecord::Associations::Association`. I've moved them to association and rewrote collection proxy's docs to be more applicable to what the class actually does.` [ci skip]
* | Refactor to just use `Association#target=` in `associate_records_to_owner`Ryuta Kamizono2019-02-091-3/+2
| | | | | | | | | | | | | | | | | | | | | | `Association#target=` invokes `loaded!`, so we no longer need to call the `loaded!` explicitly. Since Preloader is private API, we don't guarantee that it behaves like older version as long as using Preloader directly. But this refactoring fortunately also fix the Preloader compatibility issue #35195. Closes #35195.
* | Merge pull request #35178 from bogdan/has-many-sizeRyuta Kamizono2019-02-081-2/+2
|\ \ | |/ |/| Bugfix has_many association #size when ids reader is cached and assoc…
| * Bugfix has_many association #size when ids reader is cached and association ↵Bogdan Gusiev2019-02-081-2/+2
| | | | | | | | is changed
* | Fix `CollectionProxy#concat` to return self by alias it to `#<<`Yuya Tanaka2019-02-062-33/+6
|/ | | | Formerly it was returning arguments (`records` array).
* Merge pull request #35127 from bogdan/counter-cache-loadingRyuta Kamizono2019-02-052-16/+13
|\ | | | | Bugfix association loading behavior when counter cache is zero
| * Bugfix association loading behavior when counter cache is zeroBogdan Gusiev2019-02-052-16/+13
| |
* | Ensure `StatementCache#execute` never raises `RangeError`Ryuta Kamizono2019-01-182-5/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | Since 31ffbf8d, finder methods no longer raise `RangeError`. So `StatementCache#execute` is the only place to raise the exception for finder queries. `StatementCache` is used for simple equality queries in the codebase. This means that if `StatementCache#execute` raises `RangeError`, the result could always be regarded as empty. So `StatementCache#execute` just return nil in that range error case, and treat that as empty in the caller side, then we can avoid catching the exception in much places.
* | Refs #28025 nullify *_type column on polymorphic associations on :nu… ↵Laerti2019-01-153-2/+9
|/ | | | | | (#28078) This PR addresses the issue described in #28025. On `dependent: :nullify` strategy only the foreign key of the relation is nullified. However on polymorphic associations the `*_type` column is not nullified leaving the record with a NULL `*_id` but the `*_type` column is present.
* Merge pull request #34806 from bogdan/reuse-find-targetRyuta Kamizono2018-12-274-30/+20
|\ | | | | | | Reuse AR::Association#find_target method
| * Reuse AR::Association#find_target methodBogdan Gusiev2018-12-274-29/+21
| |
* | Merge pull request #34609 from kamipo/delete_all_on_collection_proxyRyuta Kamizono2018-12-042-0/+3
|\ \ | | | | | | | | | Ensure that `delete_all` on collection proxy returns affected count
| * | Ensure that `delete_all` on collection proxy returns affected countRyuta Kamizono2018-12-042-0/+3
| |/ | | | | | | | | | | | | Unlike the `Relation#delete_all`, `delete_all` on collection proxy doesn't return affected count. Since the `CollectionProxy` is a subclass of the `Relation`, this inconsistency is probably not intended, so it should return the count consistently.
* / Reset scope after collection deleteGannon McGibbon2018-12-041-4/+4
|/ | | | | Reset scope after delete on collection association to clear stale offsets of removed records.
* Revert "Merge pull request #34538 from bogdan/reuse-find-target"Ryuta Kamizono2018-11-283-23/+28
| | | | | | | This reverts commit f2ab8b64d4d46d7199f94c3e21021f414a4d259a, reversing changes made to b9c7305dbe57931a153a540d49ae5d469af61a14. Reason: `scope.take` is not the same with `scope.to_a.first`.
* Reuse code in AR::Association#find_targetBogdan Gusiev2018-11-273-29/+23
| | | | | | | Before this patch, singular and collection associations had different implementations of the #find_target method. This patch reuses the code properly through extending the low level methods.
* Optimize difference and intersectionFlorian Ebeling2018-11-061-17/+9
|
* Rename union to intersectionFlorian Ebeling2018-11-063-3/+3
|
* Fix handling of duplicates for `replace` on has_many-throughFlorian Ebeling2018-11-063-3/+41
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There was a bug in the handling of duplicates when assigning (replacing) associated records, which made the result dependent on whether a given record was associated already before being assigned anew. E.g. post.people = [person, person] post.people.count # => 2 while post.people = [person] post.people = [person, person] post.people.count # => 1 This change adds a test to provoke the former incorrect behavior, and fixes it. Cause of the bug was the handling of record collections as sets, and using `-` (difference) and `&` (union) operations on them indiscriminately. This temporary conversion to sets would eliminate duplicates. The fix is to decorate record collections for these operations, and only for the `has_many :through` case. It is done by counting occurrences, and use the record together with the occurrence number as element, in order to make them work well in sets. Given a, b = *Person.all then the collection used for finding the difference or union of records would be internally changed from [a, b, a] to [[a, 1], [b, 1], [a, 2]] for these operations. So a first occurrence and a second occurrence would be distinguishable, which is all that is necessary for this task. Fixes #33942.
* Don't expose internal `get_value`/`set_value` methodsRyuta Kamizono2018-10-181-1/+1
|
* Merge pull request #34094 from ↵Ryuta Kamizono2018-10-103-3/+5
|\ | | | | | | | | christophemaximin/fix-activerecord-clearing-of-query-cache Fix inconsistent behavior by clearing QueryCache when reloading associations
| * Clear QueryCache when reloading associationsChristophe Maximin2018-10-103-3/+5
| |
* | Don't expose internal methods in the associationsRyuta Kamizono2018-10-082-32/+32
| |
* | Fix `AssociationRelation` not to set inverse instance key just like beforeRyuta Kamizono2018-10-071-0/+8
|/ | | | | | | | | | | | | | | | | Since #31575, `set_inverse_instance` replaces the foreign key by the current owner immediately to make it happen when a record is added to collection association. But `set_inverse_instance` is not only called when a record is added, but also when a record is loaded from queries. And also, that loaded records are not always associated records for some reason (using `or`, `unscope`, `rewhere`, etc). It is hard to distinguish whether or not we should invoke `set_inverse_instance`, but at least we should avoid the undesired side-effect which was brought from #31575. Fixes #34108.
* Restore `preloaders_for_one` methodRyuta Kamizono2018-10-051-5/+9
| | | | Since the above comment is for the `preloaders_for_one`.
* Merge pull request #33938 from faucct/bugfix/preload_through_no_recordsEileen M. Uchitelle2018-10-041-28/+24
|\ | | | | ActiveRecord::Associations::Preloader should not fail to preload through missing records
| * ActiveRecord::Associations::Preloader should not fail to preload through ↵Nikita Sokolov2018-10-021-28/+24
| | | | | | | | missing records
* | Fix call sitesGannon McGibbon2018-10-021-1/+1
|/
* Add `Style/RedundantFreeze` to remove redudant `.freeze`Yasuo Honda2018-09-291-1/+1
| | | | | | | | | | | | | | | | | | | | | Since Rails 6.0 will support Ruby 2.4.1 or higher `# frozen_string_literal: true` magic comment is enough to make string object frozen. This magic comment is enabled by `Style/FrozenStringLiteralComment` cop. * Exclude these files not to auto correct false positive `Regexp#freeze` - 'actionpack/lib/action_dispatch/journey/router/utils.rb' - 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb' It has been fixed by https://github.com/rubocop-hq/rubocop/pull/6333 Once the newer version of RuboCop released and available at Code Climate these exclude entries should be removed. * Replace `String#freeze` with `String#-@` manually if explicit frozen string objects are required - 'actionpack/test/controller/test_case_test.rb' - 'activemodel/test/cases/type/string_test.rb' - 'activesupport/lib/active_support/core_ext/string/strip.rb' - 'activesupport/test/core_ext/string_ext_test.rb' - 'railties/test/generators/actions_test.rb'
* Avoid extra touch queries when counter cache is updatedRyuta Kamizono2018-09-271-2/+8
| | | | Since counter cache handles touch option too.
* Refactor counter cache to extract `decrement_counters_before_last_save` on ↵Ryuta Kamizono2018-09-272-48/+31
| | | | the belongs_to association
* Merge pull request #31819 from bpohoriletz/masterEileen M. Uchitelle2018-09-261-4/+3
|\ | | | | If association is a hash-like object preloading fails
| * If association is a hash-like object preloading failsBohdan Pohorilets2018-09-261-4/+3
| | | | | | | | | | | | If you pass a hash-like object to preload associations (for example ActionController::Parameters) preloader will fail with the ArgumentError. This change allows passing objects that may be converted to a Hash or String into a preloader
* | Revert "Remove `counter_cache_target` which is no longer called"Ryuta Kamizono2018-09-261-1/+10
| | | | | | | | | | | | | | | | This reverts commit 376ffe0ea2e59dc51461122210729c05a10fb443. Since 38fae1f, `association.increment_counters` is called without inflated parent target if inverse_of is disabled. In that case, that commit would cause extra queries to inflate parent.
* | Update counter cache in memory if parent target is existedRyuta Kamizono2018-09-261-10/+3
|/ | | | Fixes #19550.
* Remove `counter_cache_target` which is no longer calledRyuta Kamizono2018-09-261-10/+1
| | | | | `counter_cache_target` is called only when updated counter cache in replacing target, but it was already removed at #33913.
* Don't update counter cache unless the record is actually savedRyuta Kamizono2018-09-193-23/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is a 4th attempt to make counter cache transactional completely. Past attempts: #9236, #14849, #23357. All existing counter cache issues (increment/decrement twice, lost increment) are caused due to updating counter cache on the outside of the record saving transaction by assigning belongs_to record, even though assigning that doesn't cause the record saving. We have the `@_after_replace_counter_called` guard condition to mitigate double increment/decrement issues, but we can't completely prevent that inconsistency as long as updating counter cache on the outside of the transaction, since saving the record is not always happened after that. We already have handling counter cache after create/update/destroy, https://github.com/rails/rails/blob/1b90f614b1b3d06b7f02a8b9ea6cd84f15d58643/activerecord/lib/active_record/counter_cache.rb#L162-L189 https://github.com/rails/rails/blob/1b90f614b1b3d06b7f02a8b9ea6cd84f15d58643/activerecord/lib/active_record/associations/builder/belongs_to.rb#L33-L59 so just removing assigning logic on the belongs_to association makes counter cache transactional completely. Closes #14849. Closes #23357. Closes #31493. Closes #31494. Closes #32372. Closes #33113. Closes #33117 Closes #33129. Closes #33458.
* ActiveRecord::Associations::Preloader should preload all instances of the ↵Nikita Sokolov2018-09-161-1/+0
| | | | same record
* Enable Style/ParenthesesAroundCondition copRyuta Kamizono2018-08-191-1/+1
| | | | To prevent style check in review like https://github.com/rails/rails/pull/33608#discussion_r211087605.
* Extract `Relation#update_counters` for internal useRyuta Kamizono2018-07-302-13/+8
| | | | | | The target object for counter cache is not always determined by the primary key value on the model. I'd like to extract `update_couters` onto the `Relation` for the internal use.
* Avoid unneeded expanded column aliases array cachingRyuta Kamizono2018-07-102-8/+5
|
* Don't extract `readonly_value` each timeRyuta Kamizono2018-07-032-5/+7
|
* Don't share seen object cache between different join nodes in eager loadingRyuta Kamizono2018-07-031-2/+2
| | | | | | | | | | | Currently, the seen object cache is shared if join nodes have the same target class. But it is a wrong assumption, we can't share the seen object cache between different join nodes (e.g. `:readonly_account` and `:accounts` have the same target class `Account`, but the instances have the different state `readonly`). Fixes #26805. Closes #27737.
* Use `reflection.alias_candidate` in `table_alias_for`Ryuta Kamizono2018-06-261-1/+1
| | | | | | | | | | | | | | | The "join" affix in `table_alias_for` was added 12 years ago at 02d3444 to address poor alias tracking. `AssociationScope` no longer uses the "join" suffixed alias since 0408e21 and had been removed at a1ec8b5. `table_alias_for` is the last place that using the useless legacy suffixed alias, but we can't remove the suffix since some test cases directly refers the alias name by `where` with string literal, so at least removing the suffix would break our test cases. (e.g. https://github.com/rails/rails/blob/b2eb1d1c55a59fee1e6c4cba7030d8ceb524267c/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb#L699-L731).
* Remove all `aliases` passing from `JoinDependency`Ryuta Kamizono2018-06-201-2/+2
| | | | Follow up of 15367a2c674bf19eeefa12ccb64391bdd50d883d.