views:

103

answers:

3

Can anyone explain to me how the (HABTM or many to many) "has and belongs to many" principle works? Say I have a users table and books table and then I have a table users_books where the IDs are. When would I need to actually use this principle and how would it work?

+1  A: 
Robert Harvey
Right. I understand that. I just don't see the point. Why not incorporate it into one table and how does it work in an application sense?
openfractal
This is actually a relatively common pattern with relational databases. The Ruby crowd just gave it a special name, but this is always how you deal with a many-to-many relationship. You always need a "linking table" to associate the two tables.
Robert Harvey
How it works in an application sense: think of school registration. You need one record in the linking table for each student/class combination.
Robert Harvey
A: 

This section of the Rails Associations guide has some good information on the way this works in Rails. You should also consider the possibility of a through association in the event that you need to store more information about the association itself. Wikipedia has a brief article on the basic concept of many-to-many data models that may also prove instructive.

Greg Campbell
+2  A: 

Are you asking why you need many-to-many relationships (which is what HABTM is)?

In the case you mention above a user may own many books - how you you represent that in a database Lets say you have two tables, books and users, in the users table you can't add one column per book for each book the user may own as you don't know what the upper limit on the number of owned books is. You could add a column called 'books' and store a 'collection' of books in this column (maybe as XML or comma separated) but this makes lots of database queries hard (such as identifying individual books that user owns).

The same is true of the books table, how many users own a particular book? again you can't know up front so you can't add multiple 'user' columns to the books table and adding a single 'users' column with a collection of users doesn't help.

The solution to this problem is to add a 'join' table, usersbooks say, that contains two columns, a userid and a bookid. This table links the users to the books. So if I have two users with ids 1 and 2 and three books with id 101, 102 and 103 the join table may look like:

userid  bookid
1       101
2       101
2       103

This is where the users_books comes in in HABTM - it's the join table between users and books.

Kevin Jones
So one user can have multiple books? How would that look or work?
openfractal
Through the join table. I triedto illustrate in my answer but the formatting got screwed.Lets say user 1 has two books%2C in the join table there'd be two rows the first row would have userid=1 and bookid=101 and the second row userid=1 bookid=102. For user 2 you'd have rows with userid=2 bookid=101 and userid=2 bookid=103. So user 1 would have 2 books with ids 101 and 102 and user 2 would have 2 books with ids 101 and 103
Kevin Jones
I went ahead and fixed your formatting.
musicfreak
Great. Thanks. That pretty much fills in the gap.
openfractal
+1 Great explanation.
musicfreak