Many-to-Many: Adding Memberships to Rails
- Chuck Curtis
- Sep 6, 2019
- 3 min read
A key feature of the app is that users can join and leave groups that they want to be a part of. To implement this feature I set up a many-to-many relationship between users and groups by adding a new resource called Memberships. The ERD (entity relationship diagram) is as follows:

To establish this relationship in Rails, I start with generating a scaffold for the membership resource. Each membership has its own id, as well as a user id and a group id.
I run through each of the files generated by the scaffold. The migration itself is pretty straight forward so I don't need any changes there. When I get to the membership model, I see that each membership belongs to a user and a group. I need to update the relationship in the group model and user model to match the ERD. I update the group model to have many memberships, and to have many users through memberships. I do the same in the user model to reflect the relationship with memberships and groups. Below Group, User, and Membership models updated with the new relationship.
Next I review the memberships controller. Right away I know that I want to protect memberships behind user auth, so I update the memberships controller to inherit from protected controller. I don't need all of the methods for accessing memberships either. The only interactions that I need for memberships are to show all memberships for a user, to create a membership, and to delete a membership. I comment out the 'patch' request method for memberships since there won't be anything to edit. I also comment out the index method since there isn't any reason that I would want to view a list of every membership that exists. After this I head over to the routes file and update the corresponding routes for memberships to reflect the new, stricter, methods.

At this point I'm ready to start testing with curl scripts. I want to start with creating a membership, so I setup a curl script for create, and give it a go. I'm getting an error that the user doesn't exist. After some brainstorming I realize that I can update the create method on the memberships controller to use current_user.memberships.build, instead of Membership.new. Using current_user means that the user_id for the new membership will be set a the existing user. This is perfect because it's exactly what I want to do!
Now that I can create a membership which contains a user_id and a group_id, I want to test out deleting a membership. This is tricky because I need a way to access the membership id. After testing out some changes in different files I find that the membership serializer is where I need to make some updates. Instead of having the membership serializer pass along the entire user object, and the entire group object, I make a change so that the membership serializer will only pass along its own id, the user_id, and the group_id. This way I have a very simple response when I create a new membership, and also when I load a group I'm getting an array of memberships which only contain the necessary data and nothing more.

Now I find that when I request a 'show' for a specific group, I receive an array of memberships. Each element in the memberships array contains an id, a user_id, and a group_id. Suddenly I have all the info I could need for deleting a membership! Satisfied with my progress, I commit the updates.
Up next, I'll update the React client interface so that real users in the app will be able to create and delete memberships of their own. As we'll see, this is easier said than done but I'm confident that we can figure it out!
Comments