In a many to many relationship, it's just a table between the entities, but what is the purpose of this table to be between them? Let's explain it with an example, in Rails we can create two models and these 2 models can be connected just with a foreign key by Active Record Associations. rails g model User name rails g model Event name integer user_id: Now that we have created these 2 models (Don't forget to migrate the models with rails db:migrate) and , how do we connect them? Well, the is going to be our , remember that primary keys are between models, so in order to reference our model. We can start saying " r". Therefore, to make that happen we need to use the reserved words and like this: Event User user_id foreign key unique User A User can have many events but an Event belongs to one single use has_many belongs_to has_many < ApplicationRecord class User :events end belongs_to < ApplicationRecord class Event :user end Great! Now we can start playing with our associations and Rails will make 2 assumptions : 1) The class of the model your association points to is based directly off of the name of the association. 2) The foreign key in any relationship will be called belongs_to yourassociationname_id. In our we can now do something like this: Rails console user = User.new; user.name = user.save event = Event.new event.name = event.user = user "Fernando" "The big Party" Ok, so we created a new called and we created a new called thanks to our we can use and tell that specific event that it belongs to that specific user. So after we save our with User "Fernando" Event "The big Party" belongs_to event.user event event.save We can get our user for that specific event! as an Active Record with and it will return that specific user for that specific event event.user #<User id: , : , : , : > 1 name "Fernando" created_at "2020-10-06 17:14:30" updated_at "2020-10-06 17:14:30" Now to get all the events that this has we can do User user.events #<ActiveRecord::Associations::CollectionProxy [#<Event id: 1, name: "The biggest party", user_id: 1, created_at: "2020-10-06 17:33:01", updated_at: "2020-10-06 17:33:01">]> Do you see the difference? The difference is that in one query we received an while on the other query related to the events we received a , CollectionProxy is nothing more than an array since a user can have events, but remember an event can User. Active_Record CollectionProxy multiple have only 1 Now let's complicate things a little bit more... Imagine that you want your " We can think in a way to create another model called , and do another relation between and but what will be the difference between and ? They both will have the same attributes (Invitee,User) the main difference is that one is attending the event and the other one isn't? So we need to think in a way to use our model User to be distinguished as an "Owner" and as an "Invitee". users to attend many events, but only one user to be the owner for that specific event?" Invitee Invitee Event Invitee User So we can say something like this: " " and " ". We can now see clearly that we have a relationship between these 2 models. So what approach should we take? A User can have many events and can attend many events An Event can have many attendees but it only belongs to one single user Many/Many First, we need 2 Foreign-Keys one for the and one for the we can add a new column to our model with the command: Don't forget to migrate it with Owner Attendee, Event rails g migration add_column_owner_id_to_events owner_id:integer rails db:migrate. Ok, now that we have a new column called we need to specify that instead to look for to look for a column called to identify that for that user is meant to be the host of that event. owner_id user_id owner_id foreign_key owner_id has_many , , has_many , < ApplicationRecord class User :events foreign_key: "owner_id" class_name: "Event" :attending_events class_name: "Event" end Note here that I changed to to clarify that he is attending to many events but in order to do that we need to specify the , and it will go ahead and look by default foreign_key into the So if we type we will be getting the events that the first user is attending into our Rails App. :attending_events class_name user_id Event Model. User.first.attending_events Now we need to create some owners for those events, lets create 3 more users as we did before and also 1 more event. If you did everything right ... You should now have 3 Users. Now let's assign those events an owner. ev1 = Event.first ev2 = Event.second ev1.owner = User.first ev2.owner = User.second ev1.save ev2.save # Update the events with the **save** method belongs_to , has_many , , < ApplicationRecord class Event :owner class_name: "User" :attendees foreign_key: "id" class_name: "User" end Now we can see the for each event by saying for the : it will return us the ActiveRecord for that specific event, that's because we are saying to Rails to look for on in the and locate that in class, but now how can we see the attendees for that specific event? We can just type and Rails will go to the class and match with since we specificied on , else it would be looking for a field called . owner first event ev1.owner owner_id Event Model id User ev1.attendees User user.id foreign_key: "id" event_id Now, let's analyze some problems that we have here ... For example, if we create a new Attendee for the same event , imagine if we have 1,000 attendees we will have 1,000 event instance of the same event, but with different user_ids on the same model making it impossible to query it! , we will need to create the same event but with a different user_id on the Event model What should we do? Through table..... Yes, a Through table is what we need, to keep our attendees in a separate table and to leave our unique in its own model. So how does it works? Event First let's get one thing straight... Let's remove the from model with : and again.. Don't forget to migrate it with )now we have our Event model without the column, remember! that was our field to take our attendees. user_id Event rails g migration remove_user_id_from_events user_id:integer rails db:migrate (at this point im going to skip to say rails db:migrate every time we type a command on the terminal user_id Let's generate our new model to work as a communication between User & Event. By conversion this table is called by the name of the 2 models (User & Event) concatenated. So it can be called EventUser, UserEvent. I'm going to call it EventAttendee, since we want to show all of our attendees for a specific event. We generate our new model as before with: rails g model EventAttendee event_id:integer attendee_id:integer Now we set up our through table saying that the will belong to model and that will belong to model : event_id Event attendee_id User belongs_to , belongs_to , < ApplicationRecord class EventAttendee :event class_name: "Event" :attendee class_name: "User" end Now, let's configure our model to communicate with our through table. User EventAttendee has_many , , has_many , has_many , , < ApplicationRecord class User :events foreign_key: "owner_id" class_name: "Event" :event_attendees foreign_key: "attendee_id" :attending_events through: :event_attendees source: :attendee end Ok.. Let's explain what we did here... we are saying that a and to search it by and on the name of the method will be be so we can use it as and look it through ,note the attribute? that attribute is neccessary because if not we are going to look for a column called but in our model our column is called , so that's why we specify to go look for but the method name is called has_many :event_attendees, foreign_key: "attendee_id" "A user can attend many events" attendee_id has_many :attending_events, through: :event_attendees, source: attendee :attending_events E.G: User.first.event_attendees :event_attendees source: ... :attending_events EventAttendee attendee_id source: :attendee attendee_id column :attending_events Now let's configure our model to communicate with our through table. Event EventAttendee belongs_to , has_many , has_many , , < ApplicationRecord class Event :owner class_name: "User" :event_attendees foreign_key: "event_id" :attendees through: :event_attendees source: :event end Let's explain again but now with model we are saying that's why we are calling our method so we can use it as and to look it through model, since our method is called we specify with to look for with Event has_many :event_attendees, foreign_key: "event_id" "A event can have many users(attendees)" :attendees E.G: Event.first.attendees :event_attendees :attendees source: event_id :event Now we can see each of our events attendees, events owners, the events that the user is attending, and the infrastructure is pretty well organized that let us query single events for the Event model. Just by adding another table through our model in our many to many relationship...