Getting Stale Data for ActiveRecord Associations in Rails: `Model.reload` to fetch latest data

RMAG news

Issue

I encountered a bug where Associations were referencing stale data.

Here’s the sample scenario(generated by ChatGPT):

Initial State: Fetching pets

class Person < ActiveRecord::Base
has_many :pets
end
# Fetching pets from the database
person = Person.find(1)
pets = person.pets
# => [#<Pet id: 1, name: “Snoop”, group: “dogs”, person_id: 1>]

Database Update: Adding a new pet

# Simulating a direct database update (could be from another part of the application or an external source)
Pet.create(name: “Whiskers”, group: “cats”, person_id: 1)

*Accessing cached pets 🔴

cached_pets = person.pets
# => [#<Pet id: 1, name: “Snoop”, group: “dogs”, person_id: 1>]

At this point, cached_pets does not include the new pet “Whiskers” because the pets association is using the cached value.

Solution

.reload

Accessing pets with reload

updated_pets = person.pets.reload
# => [#<Pet id: 1, name: “Snoop”, group: “dogs”, person_id: 1>, #<Pet id: 2, name: “Whiskers”, group: “cats”, person_id: 1>]

Reference

# Reloads the collection from the database. Returns +self+.
#
# class Person < ActiveRecord::Base
# has_many :pets
# end
#
# person.pets # fetches pets from the database
# # => [#<Pet id: 1, name: “Snoop”, group: “dogs”, person_id: 1>]
#
# person.pets # uses the pets cache
# # => [#<Pet id: 1, name: “Snoop”, group: “dogs”, person_id: 1>]
#
# person.pets.reload # fetches pets from the database
# # => [#<Pet id: 1, name: “Snoop”, group: “dogs”, person_id: 1>]
def reload
proxy_association.reload(true)
reset_scope
end

(https://github.com/rails/rails/blob/984c3ef2775781d47efa9f541ce570daa2434a80/activerecord/lib/active_record/associations/collection_proxy.rb#L1067)