aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/models
Commit message (Collapse)AuthorAgeFilesLines
* Polymorphic has_one touch: Reset association cache result after create ↵Kasper Timm Hansen2019-07-311-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | transaction In case of a polymorphic association there's no automatic inverse_of to assign the inverse record. So to get the record there needs to be a query executed, however, if the query fires within the transaction that's trying to create the associated record, no record can be found. And worse, the nil result is cached on the association so after the transaction commits the record can't be found. That's what happens if touch is enabled on a polymorphic has_one association. Consider a Comment with a commentable association that needs to be touched. For `Comment.create(commentable: Post.new)`, the existing code essentially does `commentable.send(:comment)` within the create transaction for the comment and thus not finding the comment. Now we're purposefully clearing the cache in case we've tried accessing the association within the transaction and found no object. Before: ``` kaspth-imac 2.6.3 ~/code/rails/activerecord master *= ARCONN=postgresql bin/test test/cases/associations/has_one_associations_test.rb -n /commit/ Using postgresql Run options: -n /commit/ --seed 46022 D, [2019-07-19T03:30:37.864537 #96022] DEBUG -- : Chef Load (0.2ms) SELECT "chefs".* FROM "chefs" WHERE "chefs"."employable_id" = $1 AND "chefs"."employable_type" = $2 LIMIT $3 [["employable_id", 1], ["employable_type", "DrinkDesignerWithPolymorphicTouchChef"], ["LIMIT", 1]] D, [2019-07-19T03:30:37.865013 #96022] DEBUG -- : Chef Create (0.2ms) INSERT INTO "chefs" ("employable_id", "employable_type") VALUES ($1, $2) RETURNING "id" [["employable_id", 1], ["employable_type", "DrinkDesignerWithPolymorphicTouchChef"]] D, [2019-07-19T03:30:37.865201 #96022] DEBUG -- : TRANSACTION (0.1ms) RELEASE SAVEPOINT active_record_1 D, [2019-07-19T03:30:37.874136 #96022] DEBUG -- : TRANSACTION (0.1ms) ROLLBACK D, [2019-07-19T03:30:37.874323 #96022] DEBUG -- : TRANSACTION (0.1ms) ROLLBACK F Failure: HasOneAssociationsTest#test_polymorphic_has_one_with_touch_option_on_create_wont_cache_assocation_so_fetching_after_transaction_commit_works [/Users/kaspth/code/rails/activerecord/test/cases/associations/has_one_associations_test.rb:716]: --- expected +++ actual @@ -1 +1 @@ -#<Chef id: 1, employable_id: 1, employable_type: "DrinkDesignerWithPolymorphicTouchChef", department_id: nil, employable_list_type: nil, employable_list_id: nil> +nil ``` After: ``` kaspth-imac 2.6.3 ~/code/rails/activerecord master *= ARCONN=postgresql bin/test test/cases/associations/has_one_associations_test.rb -n /commit/ Using postgresql Run options: -n /commit/ --seed 46022 D, [2019-07-19T03:30:22.479387 #95973] DEBUG -- : Chef Create (0.3ms) INSERT INTO "chefs" ("employable_id", "employable_type") VALUES ($1, $2) RETURNING "id" [["employable_id", 1], ["employable_type", "DrinkDesignerWithPolymorphicTouchChef"]] D, [2019-07-19T03:30:22.479574 #95973] DEBUG -- : TRANSACTION (0.1ms) RELEASE SAVEPOINT active_record_1 D, [2019-07-19T03:30:22.482051 #95973] DEBUG -- : Chef Load (0.1ms) SELECT "chefs".* FROM "chefs" WHERE "chefs"."employable_id" = $1 AND "chefs"."employable_type" = $2 LIMIT $3 [["employable_id", 1], ["employable_type", "DrinkDesignerWithPolymorphicTouchChef"], ["LIMIT", 1]] D, [2019-07-19T03:30:22.482317 #95973] DEBUG -- : TRANSACTION (0.1ms) ROLLBACK D, [2019-07-19T03:30:22.482437 #95973] DEBUG -- : TRANSACTION (0.1ms) ROLLBACK . Finished in 0.088498s, 11.2997 runs/s, 22.5994 assertions/s. 1 runs, 2 assertions, 0 failures, 0 errors, 0 skips ``` Notice the select now fires after the commit.
* Merge pull request #36671 from ↵Eileen M. Uchitelle2019-07-242-0/+12
|\ | | | | | | | | wjessop/do_not_validate_non_dirty_association_targets Don't validate non dirty association targets
| * Don't validate non dirty association targetsWill Jessop2019-07-152-0/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Fixes #36581. This fixes an issue where validations would return differently when a previously saved invalid association was loaded between calls: assert_equal true, squeak.valid? assert_equal true, squeak.mouse.present? assert_equal true, squeak.valid? Here the second assert would return Expected: true Actual: false Limiting validations to associations that would be normally saved (using autosave: true) due to changes means that loading invalid associated relations will not change the return value of the parent relations's `valid?` method.
* | Fix errors getting duplicated when passed validations options:Edouard CHIN2019-07-101-1/+2
|/ | | | | | | | | | | | | | | | | | | | | | | | | | - In 86620cc3aa8e2630bc8d934b1a86453276b9eee9, a change was made on how we remove error duplication on a record for autosave association This fix has one caveat where validation having a `if` / `unless` options passed as a proc would be considered different. Example: ```ruby class Book < ApplicationRecord has_one :author validates :title, presence: true, if -> { true } validates :title, presence: true, if -> { true } end Book.new.valid? # false Book.errors.full_messages # ["title can't be blank", "title can't be blank"] ``` While this example might sound strange, I think it's better to ignore `AM::Validations` options (if, unless ...) when making the comparison.
* Merge pull request #36210 from ↵Rafael França2019-06-242-0/+7
|\ | | | | | | | | vishaltelangre/raise-record-invalid-when-associations-fail-to-save-due-to-uniqueness-failure Fix: ActiveRecord::RecordInvalid is not raised when an associated record fails to #save! due to uniqueness validation failure
| * Fix: ActiveRecord::RecordInvalid is not raised when an associated record ↵Vishal Telangre2019-05-102-0/+7
| | | | | | | | | | | | | | | | fails to #save! due to uniqueness validation failure Add tests Fix tests failing due to introduction of uniquness rule added to Book model
* | Merge pull request #35891 from Shopify/schema-cache-deduplicationKasper Timm Hansen2019-06-191-9/+9
|\ \ | | | | | | Deduplicate various Active Record schema cache structures
| * | Deduplicate various Active Record schema cache structuresJean Boussier2019-06-031-9/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Real world database schemas contain a lot of duplicated data. Some column names like `id`, `created_at` etc can easily be repeated hundreds of times. Same for SqlTypeMetada, most database will contain only a limited number of possible combinations. This result in a lot of wasted memory. The idea here is to make these data sctructures immutable, use a registry to substitute similar instances with pre-existing ones.
* | | Enable `Layout/EmptyLinesAroundAccessModifier` copRyuta Kamizono2019-06-135-5/+0
|/ / | | | | | | | | | | | | | | | | | | | | We sometimes say "✂️ newline after `private`" in a code review (e.g. https://github.com/rails/rails/pull/18546#discussion_r23188776, https://github.com/rails/rails/pull/34832#discussion_r244847195). Now `Layout/EmptyLinesAroundAccessModifier` cop have new enforced style `EnforcedStyle: only_before` (https://github.com/rubocop-hq/rubocop/pull/7059). That cop and enforced style will reduce the our code review cost.
* | Fix comment for "broken" inverse_of associations [ci skip]Petrik2019-05-281-1/+1
| |
* | Fix eager loading associations with string joins not to raise NoMethodErrorRyuta Kamizono2019-05-151-0/+1
|/ | | | Fixes #34456.
* Namespace association extension modules under the owner modelJean Boussier2019-05-021-8/+8
|
* Make scope arity check consistent (#36134)Rob Trame2019-05-011-0/+1
| | | | | | | | * Make scope arity check consistent * Add test for arity change [Rob Trame + Rafael Mendonça França]
* Fix merging left_joins to maintain its own `join_type` contextRyuta Kamizono2019-04-271-0/+1
| | | | | | | | | | | | | | | This fixes a regression for #35864. Usually, stashed joins (mainly eager loading) are performed as LEFT JOINs. But the case of merging joins/left_joins of different class, that (stashed) joins are performed as the same `join_type` as the parent context for now. Since #35864, both (joins/left_joins) stashed joins might be contained in `joins_values`, so each stashed joins should maintain its own `join_type` context. Fixes #36103.
* Merge pull request #32313 from lulalala/model_error_as_objectRafael França2019-04-241-6/+6
|\ | | | | Model error as object
| * Raise deprecation for calling `[:f] = 'b'` or `[:f] << 'b'`lulalala2019-03-311-6/+6
| | | | | | | | Revert some tests to ensure back compatibility
* | Merge pull request #35869 from ↵Ryuta Kamizono2019-04-251-1/+3
|\ \ | | | | | | | | | | | | | | | abhaynikam/35866-add-touch-option-for-has-one-association Adds missing touch option to has_one association
| * | Adds touch option to has_one associationAbhay Nikam2019-04-251-1/+3
| | |
* | | Avoid redundant `attribute_alias?` before `attribute_alias`Ryuta Kamizono2019-04-241-2/+2
|/ / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If we want to get alias resolved attribute finally, we can use `attribute_alias` directly. For that purpose, avoiding redundant `attribute_alias?` makes alias attribute access 40% faster. https://gist.github.com/kamipo/e427f080a27b46f50bc508fae3612a0e Before (2c0729d8): ``` Warming up -------------------------------------- user['id'] 102.668k i/100ms user['new_id'] 80.660k i/100ms user['name'] 99.368k i/100ms user['new_name'] 81.626k i/100ms Calculating ------------------------------------- user['id'] 1.431M (± 4.0%) i/s - 7.187M in 5.031985s user['new_id'] 1.042M (± 4.2%) i/s - 5.243M in 5.039858s user['name'] 1.406M (± 5.6%) i/s - 7.055M in 5.036743s user['new_name'] 1.074M (± 3.6%) i/s - 5.387M in 5.024152s ``` After (this change): ``` Warming up -------------------------------------- user['id'] 109.775k i/100ms user['new_id'] 103.303k i/100ms user['name'] 105.988k i/100ms user['new_name'] 99.618k i/100ms Calculating ------------------------------------- user['id'] 1.520M (± 6.7%) i/s - 7.574M in 5.011496s user['new_id'] 1.485M (± 6.2%) i/s - 7.438M in 5.036252s user['name'] 1.538M (± 5.4%) i/s - 7.737M in 5.049765s user['new_name'] 1.516M (± 4.6%) i/s - 7.571M in 5.007293s ```
* | Fix `automatic_inverse_of` not to be disabled if extension block is givenRyuta Kamizono2019-04-121-0/+4
| | | | | | | | | | | | | | | | If an association has a scope, `automatic_inverse_of` is to be disabled. But extension block is obviously not a scope. It should not be regarded as a scope. Fixes #28806.
* | Revert "Remove unused callbacks in the `Topic` model"Ryuta Kamizono2019-04-101-0/+4
| | | | | | | | | | | | | | | | This reverts commit b33ccaa6c335e2ce482c9de1aa05e4a612aa84bc. That isn't hit by `git grep`, but actually used in meta-programming... https://github.com/rails/rails/blob/b33ccaa6c335e2ce482c9de1aa05e4a612aa84bc/activerecord/test/cases/transactions_test.rb#L1020-L1028
* | Remove unused callbacks in the `Topic` modelRyuta Kamizono2019-04-101-4/+0
| |
* | Merge pull request #28155 from lcreid/belongs_toRyuta Kamizono2019-04-103-0/+18
|\ \ | | | | | | | | | Fix "autosave: true" on belongs_to of join model causes invalid records to be saved
| * | Fix circular `autosave: true`Larry Reid2018-07-233-0/+18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Use a variable local to the `save_collection_association` method in `activerecord/lib/active_record/autosave_association.rb`, instead of an instance variable. Prior to this PR, when there was a circular series of `autosave: true` associations, the callback for a `has_many` association was run while another instance of the same callback on the same association hadn't finished running. When control returned to the first instance of the callback, the instance variable had changed, and subsequent associated records weren't saved correctly. Specifically, the ID field for the `belongs_to` corresponding to the `has_many` was `nil`. Remove unnecessary test and comments. Fixes #28080.
* | | There is no need to check `null_relation?` in `empty_scope?`Ryuta Kamizono2019-04-061-0/+4
| |/ |/| | | | | `values[:extending]` includes `NullRelation` if `null_relation?`.
* | Add Relation#annotate for SQL commentingMatt Yoho2019-03-211-0/+16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch has two main portions: 1. Add SQL comment support to Arel via Arel::Nodes::Comment. 2. Implement a Relation#annotate method on top of that. == Adding SQL comment support Adds a new Arel::Nodes::Comment node that represents an optional SQL comment and teachers the relevant visitors how to handle it. Comment nodes may be added to the basic CRUD statement nodes and set through any of the four (Select|Insert|Update|Delete)Manager objects. For example: manager = Arel::UpdateManager.new manager.table table manager.comment("annotation") manager.to_sql # UPDATE "users" /* annotation */ This new node type will be used by ActiveRecord::Relation to enable query annotation via SQL comments. == Implementing the Relation#annotate method Implements `ActiveRecord::Relation#annotate`, which accepts a comment string that will be appeneded to any queries generated by the relation. Some examples: relation = Post.where(id: 123).annotate("metadata string") relation.first # SELECT "posts".* FROM "posts" WHERE "posts"."id" = 123 # LIMIT 1 /* metadata string */ class Tag < ActiveRecord::Base scope :foo_annotated, -> { annotate("foo") } end Tag.foo_annotated.annotate("bar").first # SELECT "tags".* FROM "tags" LIMIT 1 /* foo */ /* bar */ Also wires up the plumbing so this works with `#update_all` and `#delete_all` as well. This feature is useful for instrumentation and general analysis of queries generated at runtime.
* | Fixed reselect throwing NoMethodError on ActiveRecord.Abhay Nikam2019-03-031-0/+6
| |
* | Use the correct model in the testRafael Mendonça França2019-03-011-1/+1
| | | | | | | | | | This was using a model without a default scope what made the test don't break anymore if the code is removed.
* | Use dedicated `Topic` model for `SerializedAttributeTest`Ryuta Kamizono2019-02-281-4/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This fixes both #34555 and #34738. Revert "Merge pull request #34900 from gmcgibbon/fix_test_find_only_some_columns" This reverts commit ff807f823b869d3491935a096183ee2bebd58e7b, reversing changes made to 9f1a07af0499080c9fd8815705a03a4c7e8fb506. Revert "Merge pull request #34560 from gmcgibbon/fix_decorate_leak_on_serial_attr_test" This reverts commit bd62389307e138ee0f274a9d62697567a3334ea0, reversing changes made to ec66c6a2fa4ee200259341a18ecd96310f388ba3. Revert "Fix unstable `test_serialized_attribute_works_under_concurrent_initial_access` test" This reverts commit 65c4b1b50df3fa59198de2d45d1f54b61ecc7864.
* | Allow returning nil for `default_scope`Ryuta Kamizono2019-02-281-0/+1
| |
* | Fix test that was broken by adding a default scope to an existing modelRafael Mendonça França2019-02-262-0/+8
| |
* | Fix preload with nested associationsRafael Mendonça França2019-02-261-0/+2
| | | | | | | | | | | | When the middle association doesn't have any records and the inner association is not an empty scope the owner will be `nil` so we can't try to reset the inverse association.
* | Merge pull request #35327 from abhaynikam/use-delete-by-and-destroy-by-methodRyuta Kamizono2019-02-201-1/+1
|\ \ | | | | | | Replaced usage of where.delete/destroy_all with delete/destroy_by
| * | Replaced usage of where.delete/destroy_all with delete/destroy_byAbhay Nikam2019-02-201-1/+1
| | |
* | | Merge pull request #35247 from bogdan/fix-source-reflection-reset-codeRyuta Kamizono2019-02-201-0/+1
|\ \ \ | |/ / |/| | Fix reset of the source association when through association is loaded
| * | Fix reset of the source association when through association is loadedBogdan Gusiev2019-02-201-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | 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-0/+1
| | | | | | | | | | | | | | | | | | 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.
* | | Fix `order` with custom attributesRyuta Kamizono2019-02-171-0/+4
| | | | | | | | | | | | This follows up 0ee96d13de29680e148ccb8e5b68025f29fd091c.
* | | Revert "Merge pull request #35186 from ↵Ryuta Kamizono2019-02-151-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | kamipo/fix_leaking_scope_on_relation_create" This reverts commit b67d5c6dedbf033515a96a95d24d085bf99a0d07, reversing changes made to 2e018361c7c51e36d1d98bf770b7456d78dee68b. Reason: #35186 may cause that silently leaking information when people upgrade the app. We need deprecation first before making this.
* | | Revert "Chaining named scope is no longer leaking to class level querying ↵Ryuta Kamizono2019-02-142-3/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | methods" This reverts #32380, since this may cause that silently leaking information when people upgrade the app. We need deprecation first before making this.
* | | Fix `pluck` and `select` with custom attributesRyuta Kamizono2019-02-133-1/+10
|/ / | | | | | | | | | | | | | | | | Currently custom attributes are always qualified by the table name in the generated SQL wrongly even if the table doesn't have the named column, it would cause an invalid SQL error. Custom attributes should only be qualified if the table has the same named column.
* | Fix `relation.create` to avoid leaking scope to initialization block and ↵Ryuta Kamizono2019-02-071-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | callbacks `relation.create` populates scope attributes to new record by `scoping`, it is necessary to assign the scope attributes to the record and to find STI subclass from the scope attributes. But the effect of `scoping` is class global, it was caused undesired behavior that pollute all class level querying methods in initialization block and callbacks (`after_initialize`, `before_validation`, `before_save`, etc), which are user provided code. To avoid the leaking scope issue, restore the original current scope before initialization block and callbacks are invoked. Fixes #9894. Fixes #17577. Closes #31526.
* | Chaining named scope is no longer leaking to class level querying methodsRyuta Kamizono2019-02-061-0/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Active Record uses `scoping` to delegate to named scopes from relations for propagating the chaining source scope. It was needed to restore the source scope in named scopes, but it was caused undesired behavior that pollute all class level querying methods. Example: ```ruby class Topic < ActiveRecord::Base scope :toplevel, -> { where(parent_id: nil) } scope :children, -> { where.not(parent_id: nil) } scope :has_children, -> { where(id: Topic.children.select(:parent_id)) } end # Works as expected. Topic.toplevel.where(id: Topic.children.select(:parent_id)) # Doesn't work due to leaking `toplevel` to `Topic.children`. Topic.toplevel.has_children ``` Since #29301, the receiver in named scopes has changed from the model class to the chaining source scope, so the polluting class level querying methods is no longer required for that purpose. Fixes #14003.
* | Add regression test for has_many through record creationRyuta Kamizono2019-02-011-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | #33729 affected the behavior of the has_many through record creation. Since #33729, the intermediate reflection of simple has_many through association has `inverse_of` to the association, it causes extra through record creation, the extra through record required valid before the association record is saved. https://github.com/rails/rails/blob/23125378673bcc606b274027666a126573e136f8/activerecord/lib/active_record/associations/has_many_through_association.rb#L95-L102 I think that #33729 need to more work to care about has_many through association, that PR should be reverted to not break existing apps.
* | Remove unused codebogdanvlviv2019-01-301-8/+0
| | | | | | | | | | | | | | | | - Remove `fragment_cache_key` helper declaration. It was removed in e70d3df7c9b05c129b0fdcca57f66eca316c5cfc - Remove `by_private_lifo`. It is unused since a7becf147afc85c354e5cfa519911a948d25fc4d
* | Ensure `StatementCache#execute` never raises `RangeError`Ryuta Kamizono2019-01-181-0/+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-152-0/+11
| | | | | | | | | | | | (#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.
* | Don't treat begin and rollback transactions as write queriesRyuta Kamizono2018-12-111-0/+5
| | | | | | | | | | Otherwise `save` method would raise the `ReadOnlyError` against `BEGIN` and `ROLLBACK` queries.
* | Merge pull request #34572 from kamipo/fix_scoping_with_query_methodRyuta Kamizono2018-11-301-0/+1
|\ \ | | | | | | Fix the scoping with query methods in the scope block
| * | Fix the scoping with query methods in the scope blockRyuta Kamizono2018-11-301-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | Follow up #33394. #33394 only fixes the case of scoping with klass methods in the scope block which invokes `klass.all`. Query methods in the scope block also need to invoke `klass.all` to be affected by the scoping.