mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
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:
commit
40fc31c103
5 changed files with 37 additions and 12 deletions
|
@ -56,6 +56,10 @@ module ActiveRecord
|
|||
@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 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|||
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 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|||
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 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
|
|||
}
|
||||
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 @@ ActiveRecord::Schema.define do
|
|||
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 @@ ActiveRecord::Schema.define do
|
|||
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
|
||||
|
|
Loading…
Reference in a new issue