Merge pull request #36708 from rails/has-one-polymorphic-touch-dont-cache-association-result-inside-create-transaction

Polymorphic has_one touch: Don't cache association result inside crea…
This commit is contained in:
Kasper Timm Hansen 2019-07-31 06:31:50 +02:00 committed by GitHub
commit 40fc31c103
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 37 additions and 12 deletions

@ -56,6 +56,10 @@ def reset
@inversed = false
end
def reset_negative_cache # :nodoc:
reset if loaded? && target.nil?
end
# Reloads the \target and returns +self+ on success.
# The QueryCache is cleared if +force+ is true.
def reload(force = false)

@ -32,15 +32,12 @@ def self.define_validations(model, reflection)
end
end
def self.touch_record(o, name, touch)
record = o.send name
def self.touch_record(record, name, touch)
instance = record.send(name)
return unless record && record.persisted?
if touch != true
record.touch(touch)
else
record.touch
if instance&.persisted?
touch != true ?
instance.touch(touch) : instance.touch
end
end
@ -48,11 +45,9 @@ def self.add_touch_callbacks(model, reflection)
name = reflection.name
touch = reflection.options[:touch]
callback = lambda { |record|
HasOne.touch_record(record, name, touch)
}
callback = -> (record) { HasOne.touch_record(record, name, touch) }
model.after_create callback, if: :saved_changes?
model.after_create_commit { association(name).reset_negative_cache }
model.after_update callback, if: :saved_changes?
model.after_destroy callback
model.after_touch callback

@ -709,6 +709,24 @@ def test_has_one_with_touch_option_on_create
}
end
def test_polymorphic_has_one_with_touch_option_on_create_wont_cache_association_so_fetching_after_transaction_commit_works
assert_queries(4) {
chef = Chef.create(employable: DrinkDesignerWithPolymorphicTouchChef.new)
employable = chef.employable
assert_equal chef, employable.chef
}
end
def test_polymorphic_has_one_with_touch_option_on_update_will_touch_record_by_fetching_from_database_if_needed
DrinkDesignerWithPolymorphicTouchChef.create(chef: Chef.new)
designer = DrinkDesignerWithPolymorphicTouchChef.last
assert_queries(3) {
designer.update(name: "foo")
}
end
def test_has_one_with_touch_option_on_update
new_club = Club.create(name: "1000 Oaks")
new_club.create_membership

@ -10,5 +10,11 @@ class DrinkDesignerWithPolymorphicDependentNullifyChef < ActiveRecord::Base
has_one :chef, as: :employable, dependent: :nullify
end
class DrinkDesignerWithPolymorphicTouchChef < ActiveRecord::Base
self.table_name = "drink_designers"
has_one :chef, as: :employable, touch: true
end
class MocktailDesigner < DrinkDesigner
end

@ -1070,6 +1070,7 @@
create_table :cake_designers, force: true do |t|
end
create_table :drink_designers, force: true do |t|
t.string :name
end
create_table :chefs, force: true do |t|
t.integer :employable_id
@ -1077,6 +1078,7 @@
t.integer :department_id
t.string :employable_list_type
t.integer :employable_list_id
t.timestamps
end
create_table :recipes, force: true do |t|
t.integer :chef_id