When you have different models sharing the same join table in Ruby on Rails, you can create a polymorphic has_many through relationship without a hassle.
Let’s suppose that you have Task, Project and Group models and all have them have multiple members, i.e. Users. One solution is to define a seperate membership model for all models :
Yet in this solution, you’re clearly violating DRY principle, repeating common code in different models.
A better solution might be having a polymorphic membership model for all models which have a membership :
The reason we’re using source and source_type on User model for polymorphic has_many through is Rails doesn’t know which association to look for on the join model without knowing the type of source.
Yet we can further DRY our code by writing a concern instead of repeating same code on models :
Note that since Membership is not created automatically on new Group or Project creation, we’re using an after_create callback for the person who creates a group or project, thus making them members.
This way, you can call “@user.first.groups” or “user.first.projects” conveniently from the same membership model, without repeating yourself.