Many to Many Relationships in Rails

So me and my awesome Rails Meetup Group have been following Michael Hartl Rails Tutorial chapter by chapter.  More or less we have been discussing a chapter week and see where people are having problems, confusions, or just think something is interesting.

The last meeting was to go over the second half of Chapter 12. There was some confusions on what was really going on in the User Model and what the difference relationships meant.

Relationship/Associations Methods

Lets step back and look at what we had used before with a has_many relationship (association).

This would allow us access a user’s posts through @user.microposts like we used in Chapter 11 of the tutorial.

The magic of Rails obfuscates whats really going on because of some handy conventions we have. If you look at the has_many method documentation you can learn the a bunch of ‘options’  and defaults exist. So let me write the model different way but has the same results.

Options on the has_many method [doc]

  • class_name: Specify the class name of the association. (Model)
  • :foreign_key Specify the foreign key used for the association.
  • :primary_key Specify primary key for the association.
  • :dependent Controls what happens to the associated objects when their owner is destroyed.
  • :dependent  :destroy causes all the associated objects to also be destroyed.

Convention over Configuration

We are creating a relationship on a method named ‘microposts’ that maps to the Micropost model where the User’s primary key (id) is mapped to the foreign key in the micropost table (user_id). Since this is a has_many relationship a collection of Micropost objects will be returned.

We normally don’t supply the class_name, foreign_key, or primary_key because we just use the defaults based on conventions of rails. Setting options means you are configuration your associations. For obvious reasons you want to be careful and not go against conventions unless it makes sense.

Fun Fact: At  this point we could (but don’t) rename :microposts to :posts and it would work since we configured the options needed to set the correct relationship. Meaning we could write @user.posts in our controller and it would return a collection of microposts.  This is why the active/passive methods i’ll show later work.

Many to Many Relationships

There are two ways to create a many-to-many relationship. You can use the :has_and_belongs_to_many or the :has_many :through methods. The choice to choose one over the other has to do if the join table has a model class attached do it or not. Thats it. There is some thought that you shouldn’t use HABTM relationships but i’ll start off with them.

The Role-User Example Using ‘has_and_belongs_to_many’

If we wanted to relate users to roles we’d have to think a both sides of the relationship. Given a single user how many roles can they have (many). Given a single role how many users can they have (many). Thus we have a many-to-many relationship. That means we can’t merely throw the user Primary Key into any models table. Instead we need a join table where we can store both primary keys.

The conventions would mean the User’s primary key would be stored as a foreign key (user_id) in a join table (role_user) which would contain the role_id of the ‘many’ part relationship’. No other intermediate model is involved.

Lets rewrite that again using the options found in the document we could see what we’d have to write if we didn’t have conventions.

The User-User Example Using ‘has_and_belongs_to_many

On Twitter if one users followers a user then we have a relationship between two users. Given a single user how many followers can they have (many). Given a single user, lets call it the phantom user, how many people can follow them (many). So this is just another many-to-many relationship. What gets interesting is we start using terms like following and follower in the relationship. This means we have an active and a passive relationship.

Following normal conventions we’d be declaring this:

We’d have a user_user join table, with user_id and… ummmm user_id? as the PK and FK…. you see why this isn’t going to work. Also using @user.users isn’t very meaningful to us either. So lets call the table relationships and the keys follower_id and following_id.

Conversely, we could reverse the foreign and associated keys and get the ‘followers’ relationship.

The User-User (Relationship) Example Using ‘has many through”

Recall the :has_many :through requires you to have an intermediate model. So what if instead of user_user we had a Relationship model mapped to a relationships table like in Hartl’s Listing 12.3

One the User model we can’t just say the user has many relationships because we aren’t using ‘user_id’ as the key in relationships but follower_id and followed_id.

In the end Hartl split up the ‘active’ and ‘passive’ relationships and make them methods we can use for testing, form building, record creating, and to use in other relationships.

Lets look at the documentation on has_many to see some of these new options.

  • through: Specifies an association through which to perform the query. This can be any other type of association, including other :through associations.
  • source: Specifies the source association name used by has_many :through queries.

So through means we are using an association, which could be a model or  (as we use here) other relationship functions we’ve specified ourselves. We declared the active_relationships relationship (association) and then use it in the has many through association.

I’ll have to play with source a little more to really understand it.


  • Rails conventions are awesome and they save us a lot of time
  • You can override those conventions with options available on the association methods.
  • There are two ways to define a many-to-many relationship in Rails, and which one you use depends on if you have a model table that is used a join table.
  • Some people think you shouldn’t use HABTM

My Experience Coaching at Rails Girls LA 2015

So about two weeks ago I had the pleasure of being a coach at a Rails Girls LA workshop.  It was a fantastic and rewarding experience and I want to encourage others to join and help coach/mentor similar events.

“Our aim is to give tools and a community for women to understand technology and to build their ideas. We do this by providing a great experience on building things and by making technology more approachable.”

Their mission really spoke to me. Even when I was was in highschool and doing web development for fun as a personal hobby I never really thought as programming as a career I could go into. I suffered from a lot of the self doubt and lack of role models many girls face when considering a STEM career.

Event Coaches Are Students

A couple of us who were coaching actually got together prior to the workshop and ran though the Rails Girls Guide with other coaches . We used a mob programming approach we’d be using during the workshop to try and make sure we could articulate what we wanted people to do or learn

If you are newer to command line and to rails application structure things can be tricky.  If someone tells you to “type cat app controllers” chances are they will type “catappsontrollers”. So it was a good experience trying to make sure I could give the best instructions without making my students feel frustrated or, even worse, stupid because they thought they had made the mistake rather I had given poor instructions for their level.

From Zero To Hero

So prior to showing up students are encouraged to learn some basic of ruby, github, and command line. Rails Girls LA provided some great resources so the students could be introduced to those topics before they had an environment of their own set up. The workshop consists of a “Installation Party” the night before to help everyone get started.  Either they would help you set up natively or you would be given a Virtual Machine created by the very awesome Ashok Modi so that you could be sure the full stack would work.

Let the Learning Begin

Rails Girls Guide: At the end of the day you should
  • Feel comfortable in the terminal
  • Know about ERB (Embeded Ruby) and how to use it
  • Know how to start a new Rails project
  • Have your project online
  • Know the difference between your local and remote code
  • Be comfortable in git
  • Know what MVC means
  • Learn some markdown
  • Have added a Gem to your project
  • Know about our friend Bundler
  • Meet new friends to learn with
  • Find a mentor
  • Get resources to continue learning
  • Have Fun! <3

So after some great words by some organizers and sponsors I got my two students and we hit the ground running. Me and my students followed the Rails Girls Guide to introduce them to Rails and related web technologies.

Both my students were new to command line so I was really glad I had got to the coaching mob programming session because it made things a lot easier. As we qalked through the guide I filled in the blanks of the different technologies involved and how to look up more information on certain parts and what to really focus on when learning.

After finishing a section we’d walk-through the front end portions so we could test their app and I’d try to reenforce ideas like CRUD and HTTP Verbs. I focused more on the structure of the application then trying to hammer in what MVC really is. I also tried to focus on how to talk the ‘right’ question on google and mentioned how many times I probably google things in a given day. We talked about personalized touches they could make to their applications later.

Never Stop Learning or Giving Back

It was a extremely rewarding experience and I really hope I inspired those girls to continue on and keep learning. I learn new things all the time and I learn a lot with others helping me or me helping other people accomplish their tasks at work. Collaboration is a big reason I have learned so much over the past couple of years.

Sometimes when you are struggling with the next tough problem you lose sight of how far you’ve really come. Everyone seemed to have a blast at Rails Girls, student and coaches a like. It was great seeing the Rails community come out and help introduce people to Rails and web technologies. If there isn’t a Rails Girls event in your area they have some amazing guides on setting up your own event.

Special thanks to Jen Diamond for putting together a Rails Girls event in LA!

Rails Girls LA 2015 Coach