How to see all available associations of one specific object in Rails?

alexandrecalaca

Alexandre Calaça

Posted on July 1, 2023

How to see all available associations of one specific object in Rails?

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.


três gatinhos de cores sortidas


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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

The result is going to be an array of associations.

User.last.class.reflect_on_all_associations.is_a?(Array)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
---------------------
Enter fullscreen mode Exit fullscreen mode

Be happy

You got here. Way to go!

The Office GIF - The Office Happy - Discover & Share GIFs


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.


💖 💪 🙅 🚩
alexandrecalaca
Alexandre Calaça

Posted on July 1, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related