Skip to content

Commit

Permalink
Merge pull request #46383 from dmytro-savochkin/fix-activerecord-relo…
Browse files Browse the repository at this point in the history
…ad-association-cache

Ensure `reload` sets correct owner for each association (ActiveRecord::Persistence)
  • Loading branch information
rafaelfranca committed Jan 15, 2024
1 parent 81c8023 commit 57a50f5
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 1 deletion.
3 changes: 2 additions & 1 deletion activerecord/lib/active_record/associations/association.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ module Associations
# <tt>owner</tt>, the collection of its posts as <tt>target</tt>, and
# the <tt>reflection</tt> object represents a <tt>:has_many</tt> macro.
class Association # :nodoc:
attr_reader :owner, :target, :reflection, :disable_joins
attr_accessor :owner
attr_reader :target, :reflection, :disable_joins

delegate :options, to: :reflection

Expand Down
1 change: 1 addition & 0 deletions activerecord/lib/active_record/persistence.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1076,6 +1076,7 @@ def reload(options = nil)
end

@association_cache = fresh_object.instance_variable_get(:@association_cache)
@association_cache.each_value { |association| association.owner = self }
@attributes = fresh_object.instance_variable_get(:@attributes)
@new_record = false
@previously_new_record = false
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

require "cases/helper"
require "models/publication"
require "models/editorship"
require "models/editor"

class ReloadAssociationCacheTest < ActiveRecord::TestCase
def test_reload_sets_correct_owner_for_association_cache
publication = Publication.create!(name: "Rails Way")
assert_equal "Rails Way (touched)", publication.name
publication.reload
assert_equal "Rails Way", publication.name
publication.transaction do
publication.editors = [publication.build_editor_in_chief(name: "Alex Black")]
publication.save!
end
assert_equal "Rails Way (touched)", publication.name
end
end
8 changes: 8 additions & 0 deletions activerecord/test/models/editor.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

class Editor < ActiveRecord::Base
self.primary_key = "name"

has_one :publication, foreign_key: :editor_in_chief_id, inverse_of: :editor_in_chief
has_many :editorships
end
6 changes: 6 additions & 0 deletions activerecord/test/models/editorship.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

class Editorship < ActiveRecord::Base
belongs_to :publication
belongs_to :editor
end
16 changes: 16 additions & 0 deletions activerecord/test/models/publication.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

class Publication < ActiveRecord::Base
belongs_to :editor_in_chief, class_name: "Editor", inverse_of: :publication, optional: true
has_many :editorships
has_many :editors, through: :editorships

after_initialize do
self.editor_in_chief = build_editor_in_chief(name: "John Doe")
end

after_save_commit :touch_name
def touch_name
self.name = "#{name} (touched)"
end
end
14 changes: 14 additions & 0 deletions activerecord/test/schema/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,15 @@
t.index [:source_id, :sink_id], unique: true, name: "unique_edge_index"
end

create_table :editorships, force: true do |t|
t.string :publication_id
t.string :editor_id
end

create_table :editors, force: true do |t|
t.string :name
end

create_table :engines, force: true do |t|
t.references :car, index: false
end
Expand Down Expand Up @@ -1039,6 +1048,11 @@
t.integer :mentor_id
end

create_table :publications, force: true do |t|
t.column :name, :string
t.integer :editor_in_chief_id
end

create_table :randomly_named_table1, force: true do |t|
t.string :some_attribute
t.integer :another_attribute
Expand Down

0 comments on commit 57a50f5

Please sign in to comment.