Convert a Rails association from “has and belongs to many” to “has many through”
All steps I took to convert an association in my project
--
There are a lot of blog posts that warn you about not using the Rails has_and_belongs_to_many association since you can’t predict when you will need additional functionality on the join model.
I did it anyways. Of course I ended up having to convert to a has_many :through association.
Here’s how I did it.
Original models
Update the associations
Updating models up front means that the migrations you will write shortly have to work with the updated associations. If you don’t do that you might have problems running the migrations in production.
Create a new join table
The automatic table join was called teams_users and doesn’t have an id.
Create a new table with an id and the belongs_to fields.
Migrate the data
Here’s the important bit: copy all the rows from the old join table to the new one.
Do this by using a local version of the ActiveRecord models with both associations in it.
Note that it’s not necessary to have the 2 associations in both the User and Team models, but it doesn’t hurt and I find it helped me write the correct migration code in the up method on the first try.
Drop the old join table
Rename the new table
Next time I know that I’ll be using a has many through association from the start!