This little article shows one way to model many-to-many relationships using a join table.
Obviously, The Penguin isn’t the first so here is an alternative good practical example which might give your good self an different perspective. Also this documentation has some more detailed information but doesn’t have a simple self contained example like below (and neglects to mention belongs_to in its primary example - at time of writing this).
Here goes. The following statements define our basic requirements.
- An order has many items
- An item has many orders
We shall model this through a join table called order_items
orders order_items items ----- ---------- ---- id order_id id item_id
Before we continue, please note that a massive massive thing to remember is that Order needs to have a has_many to the join table model AS WELL as a has_many (through the join table model) to Item. Also the join table model has a belongs_to for each model.
class Order < ActiveRecord::Base has_many :order_lines #Don't forget this line! has_many :items, :through => :order_lines end class Item < ActiveRecord::Base has_many :order_lines #Don't forget this line! has_many :orders, :through => :order_lines end class OrderLine < ActiveRecord::Base belongs_to :order belongs_to :item end
Ok so that’s it folks! The Penguin has to admit that the above code hasn’t been run in a RoR interpreter so if has typo’s or smelly code please comment below.
One last thing is that if you’re going to try and present a RoR solution in an enterprise situation it is quite likely that the powers that be will want to see foreign key relationships in your database tables (note, this applies to all db relationships; not just man-to-many). These will give referential integrity to your associations. One very very handy and straightforward way to do this is using Red Hill’s foreign_key_migrations plugin. This really is great (it does pretty much all the hard work for you!) so it’s worth a serious look.
One gotcha with using foreign keys in Rails, is that the order in which test fixtures load becomes important. See Per Olesen’s post for tips on countering this. Other than that happy hacking and may the Rails Rise to Meet You!