Active Associations

October 22, 2020

Working in a legacy code base, you will come across a lot of join tables and belongs-to-through complexity. You can visualize these associations using an ERD, or you can find them in the console by using

<ModelName>.reflect_on_all_associations.map(&:name)

For example, I am testing out the Thredded forum gem, and found a lot of complex join tables to navigate. I wanted to find all the ways I could access data in the UserTopicFollows join table:

> Thredded::UserTopicFollow.reflect_on_all_associations.map(&:name)
=> [:user, :topic]

So, I can get there through a Topic. That makes sense, since it is a join table.

> Thredded::Topic.reflect_on_all_associations.map(&:name)
=> [:last_user,
 :slugs,
 :user,
 :messageboard,
 :user_detail,
 :posts,
 :first_post,
 :last_post,
 :topic_categories,
 :categories,
 :user_read_states,
 :user_follows,
 :followers,
 :likes]

And I can get to Posts from Topics. That also makes sense, since Posts belong to Topics.

2.7.0 :001 > Thredded::Post.reflect_on_all_associations.map(&:name)
 => [:user, :messageboard, :postable, :user_detail, :moderation_records, :user_notifications, :last_moderation_record]

It doesn’t look like I can get back to Topic from Post, however. Since a Post belongs to a Topic, I expected that association to be in the list. That :postable association was unexpected as well, and I couldn’t find a Postable model. It turns out that postable is an alias for Topic in a UserTopicFollow join table:

module Thredded
  class UserTopicFollow < ActiveRecord::Base
  ...
  alias_attribute :postable, :topic
  ...

While my head is still spinning a bit.. I found what I needed to get unblocked. 🙃


Katie Leonard

Mostly Katie explaining things to herself.

© 2025