How to see all available associations of one specific object in Rails?
Alexandre Calaça
Posted on July 1, 2023
TL;DR: The secret is the method
reflect_on_all_associations
Problem
How to see all available associations of one specific object in Rails?
Introduction
When working on software development, developers often need to find strong relationships between objects in their database.
Ruby on Rails provides a powerful feature called associations, which allows us to establish connections between different models and access related data effortlessly.
Besides using Rails models to check the relationships, there's an interesting approach that is usually unknown by Rails developers.
In this article, we will explore a simple yet effective approach to gain insights into all available associations of a particular object within a Rails application.
Context
Basically, we need to find the object, use the keyword class
on it and then call the reflect_on_all_associations
method.
This solution was tested in the following Rails versions: 3.2, 6.1 and 7.0.
Let's dive in.
Situation
Let's think about a User model. The User model has relationships with posts, comments and likes.
Find the object
Open rails console
.
I'm going to use the last User
.
User.last
Get the class
In order to use the methods provided by the class
keyword, let's get the class of the object:
User.last.class
Now, we'll be able to use the reflect_on_all_associations
built-in Ruby function:
User.last.class.respond_to?(:reflect_on_all_associations)
The previous method returns true, since the reflect_on_all_associations
method is available to the object caller.
Retrieve associations information
User.last.class.reflect_on_all_associations
The result is going to be an array of associations.
User.last.class.reflect_on_all_associations.is_a?(Array)
As you can see, the output is too broad, it's possible to narrow it down a little.
In case you want to learn more about the reflect_on_all_associations
method and its class, click here (article in progress).
Refine the result
Let's retrieve the associations and store them in a variable:
associations = user.class.reflect_on_all_associations
Select only name
, type
and class_name
:
associations.each do |association|
puts "Name: #{association.name}"
puts "Type: #{association.macro}"
puts "Associated Class: #{association.class_name}"
puts "---------------------"
end
The previous code iterates over the associations' array and prints the name, type (macro), and associated class name for each association.
It's used the name, macro, and class_name methods of the AssociationReflection objects.
The output would be something like this:
Name: posts
Type: has_many
Associated Class: Post
---------------------
Name: comments
Type: has_many
Associated Class: Comment
---------------------
Name: likes
Type: has_many
Associated Class: Like
---------------------
Be happy
You got here. Way to go!
Let's become friends
Final thoughts
I hope this article helped you. Let me know if you have any questions. Your thoughts, suggestions and corrections are more than welcome. By the way, feel free to drop your suggestions on new blog articles.
Hope to see you next time.
Posted on July 1, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.