Rails 7.1 empowers the resetting of singular associations

railsDecember 26, 2023Dotby Alkesh Ghorpade

In Rails 7.1, models with has_one and belongs_to associations now have a method named reset_association (where the association is the actual association name) that clears any cached data for that association, ensuring the most up-to-date information is fetched from the database the next time it's accessed.

Rails has provided a reload method. It applies to various associations, which forces Rails to reload the association data from the database, ensuring you're working with the most up-to-date information. Unlike reset, it eager-loads the associated data from the database.

Before Rails 7.1

Let's say you have a Rails application with Post, Comment and Author models with associations as below:

class Post < ApplicationRecord
  has_many :comments
  belongs_to :author
end

class Comment < ApplicationRecord
  belongs_to :post
end

class Author < ApplicationRecord
  has_many :posts
end

The reset method is available on associations like has_many but is missing for singular associations like has_one or belongs_to. When you try to execute reset on the singular associations, it raises NoMethodError.

post = Post.first

# let's the post has 5 comments
post.comments
=> [<Comment id: 1, >, <Comment id: 2........]

post.comments.size
=> 5

Comment.find([1, 2]).delete_all

# stale data with post and comments object
post.comments.size
=> 5

# you need to reset or reload to fetch the fresh data from DB
post.comments.reset.size
=> 3

post.author
=> <Author id: 1, name: .....>

post.author.reset
=> `method_missing': undefined method `reset' for #<Author id: 1....

You need to use the reload method on the Author object to resolve the above issue.

post.author
=> <Author id: 1, name: .....>

Author.find(1).delete

post.author.reload
=> nil

The problem with the reload method is that it eagerly loads the associated object by firing a database query. There can be cases when you don't require the associated object data immediately, and the association can be loaded when required.

In Rails 7.1

Rails 7.1 allows the resetting of singular associations. has_one and belongs_to associations now define a reset_association method on the owner model (where the association is the association's name).

You can now lazily load the singular association record when required. The reset method will not fire any query the moment it is called. When the singular association is used, the database query will be fired.

post.author
=> <Author id: 1, name: "Sam",.....>

post.author.name
=> "Sam"

Author.find(1).update(name: "Sam Updated")

post.author.name
=> "Sam"

post.reset_author
# No query is fired

post.author.name
# query is fired now
=> "Sam Updated"

To know more about this feature, please refer to this PR.

Closing Remark

Could your team use some help with topics like this and others covered by ShakaCode's blog and open source? We specialize in optimizing Rails applications, especially those with advanced JavaScript frontends, like React. We can also help you optimize your CI processes with lower costs and faster, more reliable tests. Scraping web data and lowering infrastructure costs are two other areas of specialization. Feel free to reach out to ShakaCode's CEO, Justin Gordon, at justin@shakacode.com or schedule an appointment to discuss how ShakaCode can help your project!
Are you looking for a software development partner who can
develop modern, high-performance web apps and sites?
See what we've doneArrow right