aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/associations
Commit message (Collapse)AuthorAgeFilesLines
...
* | | `target` in `CollectionAssociation` is always an arrayRyuta Kamizono2018-04-211-2/+2
| | | | | | | | | | | | | | | So `target.is_a?(Array)` is meaningless, and just use `target.empty?` instead of `target.blank?`.
* | | Can preload associations through polymorphic associationsDana Sherson2018-04-201-10/+15
|/ /
* | Don't unset foreign key when preloading missing recordEugene Kenny2018-03-241-2/+2
| | | | | | | | | | | | | | | | | | When a belongs to association's target is set, its foreign key is now updated to match the new target. This is the correct behaviour when a new record is assigned, but not when the existing record is preloaded. As long as we mark the association as loaded, we can skip setting the target when the record is missing and avoid clobbering the foreign key.
* | Fix dependence on has_one/belongs_to relationshipsFernando Gorodscy2018-03-062-1/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When a class has a belongs_to or has_one relationship with dependent: :destroy option enabled, objects of this class should not be deleted if it's dependents cannot be deleted. Example: class Parent has_one :child, dependent: :destroy end class Child belongs_to :parent, inverse_of: :child before_destroy { throw :abort } end c = Child.create p = Parent.create(child: c) p.destroy p.destroyed? # expected: false; actual: true; Fixes #32022
* | Eager loading with polymorphic associations should behave consistentlyRyuta Kamizono2018-03-041-4/+2
| | | | | | | | | | | | | | | | | | | | This reverts ignoring polymorphic error introduced at 02da8ae. What the ignoring want to solve was caused by force eager loading regardless of whether it is necessary, but it has been fixed by #29043. The ignoring is now only causing a mismatch of `exists?` behavior with `to_a`, `count`, etc. It should behave consistently.
* | Extract all `base_class.name` as `polymorphic_name`Ryuta Kamizono2018-03-044-8/+8
| | | | | | | | | | | | | | 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.
* | Remove staled comment for `JoinDependency#initialize`Ryuta Kamizono2018-03-021-21/+0
| | | | | | | | | | | | | | | | | | | | | | This comment was added at 070dda2. That arguments has already been changed since those are internal nodoc classes, but the comment does not reflect the current state. I decided to remove the staled comment since it is not useful for understanding what the class does. [ci skip]
* | Association creation and finding should work consistently (#32048)Ryuta Kamizono2018-02-261-1/+1
| | | | | | | | | | | | | | | | | | | | | | 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.
* | Use private attr_readerRyuta Kamizono2018-02-233-4/+3
| | | | | | | | | | Since #32028, Rails 6 requires Ruby 2.3+. No longer needed workaround for Ruby 2.2 "private attribute?" warning.
* | Association scope's own order should be prioritized over through scope's orderRyuta Kamizono2018-02-181-2/+2
| | | | | | | | | | | | | | | | | | | | 3acc5d6 was changed the order of scope evaluation from through scope to the association's own scope to be prioritized over the through scope. But the sorting order will be prioritized that is evaluated first. It is unintentional effect, association scope's sorting order should be prioritized as well. Fixes #32008.
* | Rails 6 requires Ruby 2.3+Jeremy Daer2018-02-171-5/+1
| |
* | Fix marshaling of models with `has_many :through` associationsfatkodima2018-02-081-2/+2
| |
* | Revert "✂️"Ryuta Kamizono2018-02-071-1/+2
| | | | | | | | | | | | | | | | This reverts commit 487a1061cc496455dfe5ee84d1e49d509c1675b5. This `#--` is necessary for the doc of `distinct`. [ci skip]
* | ✂️schneems2018-02-061-2/+1
| |
* | Avoid extra calls to to_sDaniel Colson2018-01-292-3/+3
| | | | | | | | | | | | | | 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.
* | Avoid passing unnecessary arguments to relationDaniel Colson2018-01-242-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | Most of the time the table and predicate_builder passed to Relation.new are exactly the arel_table and predicate builder of the given klass. This uses klass.arel_table and klass.predicate_builder as the defaults, so we don't have to pass them in most cases. This does change the signaure of both Relation and AssocationRelation. Are we ok with that?
* | Fix building has_one through recordRyuta Kamizono2018-01-233-14/+10
| | | | | | | | Fixes #31762.
* | Don't update counter cache when through record was not destroyedEugene Kenny2018-01-141-1/+1
| | | | | | | | | | | | When removing a record from a has many through association, the counter cache was being updated even if the through record halted the callback chain and prevented itself from being destroyed.
* | Don't pass garbage args to alias trackerRyuta Kamizono2018-01-141-10/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | This is a complete fix to #30995. Originally alias tracker will only track table aliases on `Arel::Nodes::Join`, other args are ignored. Since c5ab6e5, parent aliases hash will be passed then it caused the regression #30995. It is enough to pass list of `Arel::Nodes::Join` simply, not need to pass garbage args which will be ignored.
* | Merge pull request #23146 from piotrj/issue_18424Ryuta Kamizono2018-01-111-0/+1
|\ \ | | | | | | | | | When deleting through records, take into account association conditions
| * | When deleting through records, take into account association conditionsPiotr Jakubowski2016-05-041-8/+9
| | | | | | | | | | | | | | | | | | | | | | | | Fixes #18424. When deleting through records, it didn't take into account the conditions that may have been affecting join model table, but was defined in association definition.
* | | Fix `stale_state` for nested `has_many :through` associationsRyuta Kamizono2018-01-101-2/+13
| | | | | | | | | | | | Need reloading when through record has replaced.
* | | Merge pull request #16314 from ↵Ryuta Kamizono2018-01-101-1/+1
|\ \ \ | | | | | | | | | | | | | | | | | | | | zoltankiss/allow-nested-has-many-associations-on-unpersisted-parent-instances fix nested `has many :through` associations on unpersisted parent instances
| * | | Fix nested `has many :through` associations on unpersisted instancesZoltan Kiss2015-03-261-1/+1
| | | | | | | | | | | | | | | | Fixes: #16313
* | | | Bring back passing single record support for `Preloader`Ryuta Kamizono2018-01-101-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I removed redundant `Array.wrap(records)` since `Preloader` is nodoc class and Active Record always pass `records` as an array to `Preloader`. But if users relies on that behavior, it is not worth dropping its behavior. Fixes #31661.
* | | | Fix deleting through records when using has_many through with `source_type`Ryuta Kamizono2018-01-081-8/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Currently deleting through records doesn't respect `source_type`. It should not be ignored in that case. Related #23209. Fixes #24116.
* | | | Simply use `scope.delete_all` instead of constructing delete managerRyuta Kamizono2018-01-071-8/+1
| | | |
* | | | Remove passing argument to singular and collection association readersRyuta Kamizono2018-01-051-2/+2
| | | | | | | | | | | | | | | | Follow up of 09cac8c67afdc4b2a1c6ae07931ddc082629b277.
* | | | Merge pull request #27561 from fishbrain/count-all-in-has-many-associationRyuta Kamizono2018-01-031-1/+1
|\ \ \ \ | | | | | | | | | | | | | | | Use `count(:all)` in HasManyAssociation#count_records
| * | | | Use `count(:all)` in HasManyAssociation#count_recordsKlas Eskilson2017-02-071-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: Calling `count` on an association can cause invalid SQL queries to be created where the `SELECT COUNT(a, b, c)` function receives multiple columns. This will cause a `StatementInvalid` exception later on. Solution: Use `count(:all)`, which generates a `SELECT COUNT(*)...` query independently of the association. This also includes a test case that, before the fix, broke.
* | | | | Remove `association_primary_key_type` from `AssociationReflection` and ↵Ryuta Kamizono2018-01-011-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | `ThroughReflection` This method was introduced in #26718, which is internally used only in `CollectionAssociation`. There is no need to be in the reflection classes.
* | | | | Bugfix foreign key replacement in inverse associationBogdan Gusiev2017-12-272-13/+8
| | | | | | | | | | | | | | | | | | | | when model is added to collection association
* | | | | Fix conflicts `counter_cache` with `touch: true` by optimistic locking.bogdanvlviv2017-12-122-5/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ``` # create_table :posts do |t| # t.integer :comments_count, default: 0 # t.integer :lock_version # t.timestamps # end class Post < ApplicationRecord end # create_table :comments do |t| # t.belongs_to :post # end class Comment < ApplicationRecord belongs_to :post, touch: true, counter_cache: true end ``` Before: ``` post = Post.create! # => begin transaction INSERT INTO "posts" ("created_at", "updated_at", "lock_version") VALUES ("2017-12-11 21:27:11.387397", "2017-12-11 21:27:11.387397", 0) commit transaction comment = Comment.create!(post: post) # => begin transaction INSERT INTO "comments" ("post_id") VALUES (1) UPDATE "posts" SET "comments_count" = COALESCE("comments_count", 0) + 1, "lock_version" = COALESCE("lock_version", 0) + 1 WHERE "posts"."id" = 1 UPDATE "posts" SET "updated_at" = '2017-12-11 21:27:11.398330', "lock_version" = 1 WHERE "posts"."id" = 1 AND "posts"."lock_version" = 0 rollback transaction # => ActiveRecord::StaleObjectError: Attempted to touch a stale object: Post. Comment.take.destroy! # => begin transaction DELETE FROM "comments" WHERE "comments"."id" = 1 UPDATE "posts" SET "comments_count" = COALESCE("comments_count", 0) - 1, "lock_version" = COALESCE("lock_version", 0) + 1 WHERE "posts"."id" = 1 UPDATE "posts" SET "updated_at" = '2017-12-11 21:42:47.785901', "lock_version" = 1 WHERE "posts"."id" = 1 AND "posts"."lock_version" = 0 rollback transaction # => ActiveRecord::StaleObjectError: Attempted to touch a stale object: Post. ``` After: ``` post = Post.create! # => begin transaction INSERT INTO "posts" ("created_at", "updated_at", "lock_version") VALUES ("2017-12-11 21:27:11.387397", "2017-12-11 21:27:11.387397", 0) commit transaction comment = Comment.create!(post: post) # => begin transaction INSERT INTO "comments" ("post_id") VALUES (1) UPDATE "posts" SET "comments_count" = COALESCE("comments_count", 0) + 1, "lock_version" = COALESCE("lock_version", 0) + 1, "updated_at" = '2017-12-11 21:37:09.802642' WHERE "posts"."id" = 1 commit transaction comment.destroy! # => begin transaction DELETE FROM "comments" WHERE "comments"."id" = 1 UPDATE "posts" SET "comments_count" = COALESCE("comments_count", 0) - 1, "lock_version" = COALESCE("lock_version", 0) + 1, "updated_at" = '2017-12-11 21:39:02.685520' WHERE "posts"."id" = 1 commit transaction ``` Fixes #31199.
* | | | | 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.