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. 🙃