The concept of one to many is that one table of data can relate to another data of table through a parent-child relationship in that an instance on table A can have multiple related instances on table B. This works except when you want to relate many to many, what happens when table A and table B have shared relationships where different combinations are needed; this is solved with association tables.
An example of a many-to-many relationship might be: If you decided to buy a car, a 1970 Dodge Charger, where would you store information such as the VIN? If you were to store the VIN in the “cars” table where you store the car’s information such as the year, make and model then you would only be able to sell that car once and would be unable to sell another without adding another row to your car’s table and redundantly adding the year, make and model again. To more efficiently store information, we can store the year, make and model in the car model, while storing the buyer’s information in it’s own model, we store the unique instance of a car and a buyer in a join table. This join table can hold any unique information tied to that sale such as VIN number, form of payment or status of sale.
If table A stores our buyers, and table B stores our cars- we will need an association table (table C) to hold the unique instances where a specific car and buyer meet. Table C will by nature hold foreign keys (a unique identifier from each table) as well as any information that is part of a unique combination between buyer and a specific car (physically.)
With a many to many relationship, we will want to associate table A and table B with a join table, table C. After we have created our table A and table B models, we can create another model that will act as a join table by adding unique identifiers from each table, this can easily be done with the default “ID” parameter that is generated and assigned to each entity in a table. Table C will store the ID parameter from table A and table B, this is required to create a join table.
Once the tables have been linked, we must back our association with logic by adding the following code to the respective controllers for each table. For clarity we will name the tables as follows: Table A will be “Buyers”, Table B will be “Cars” and table C will be “Car_Purchases”.
Controller for “Buyers”:
has_many :cars, :through => :car_purchases
Controller for “Cars”:
has_many :buyers, :through => :car_purchases
Controller for “Car_Purchases”:
Note: There are scenarios where you might have a one to many and a many to many between the same tables; please reference this link for more information about using “source.”
Rails generates several commands for us using the above code, but most importantly, either table can use the name of the other table as a method to call combination rows. In the above example, this would allow us to find out exactly which cars a buyer owns and who owns a specific vehicle and all of the information involving the sale.