has_and_belongs_to_many in Rails
Asked Answered
R

4

22

Is there anything explicitly wrong with using has_and_belongs_to_many associations in rails instead of has_many :through? I'm aware of these articles describing differences and work arounds, but they are from 2006. From things I've read on SO, it seems like people think that habtm is old and clunky, but what if a simple many to many join with no model necessary is what you're looking for?

Thoughts?

Registry answered 18/3, 2009 at 13:16 Comment(0)
M
29

has_and_belongs_to_many is meant for simple many-to-many relationships.

has_many :through, on the other hand, is meant for indirect one-to-many relationships, or many-to-many relationships with properties.

If you're only looking for a simple many-to-many relationship, I can't see any reason not to use has_and_belongs_to_many.

Example many-to-many relationship:

User belongs to zero or more groups, and group has zero or more members (users).

Example many-to-many relationship with properties:

User belongs to zero or more groups, and group has zero or more members with ranks.

For example, Alice might be an Administrator in Group A, and a Moderator in Group B. You can hold this property in the join table.

Example indirect one-to-many relationship:

A category has zero or more sub-categories, and each sub-category has zero or more items.

A category therefore has zero or more items through its sub-categories.

Consider these categories:

Food → Fruits, Vegetables
Fruits → Apple, Orange, etc.
Vegetables → Carrot, Celery, etc.

therefore:

Food → Apple, Orange, Carrot, Celery, etc.

Makeweight answered 18/3, 2009 at 13:22 Comment(2)
To understand recursion you must first understand recursion. I think your answer could be more clear or demonstrative regarding many-to-many relationships with properties vs. many-to-many relationships without properties.Hanser
how can you use this with accept_nested_attribute_for ? thanksGudrin
W
3

There's nothing wrong with using has_and_belongs_to_many if you don't require a join model. I've just used it myself on a recent project.

Wizardly answered 18/3, 2009 at 13:36 Comment(1)
how can you use this with accept_nested_attribute_for ? thanksGudrin
D
3

I would never use HABTM not because of any concern about elegance but because I can always imagine wanting to add data to a relationship in the future even if I can't see the point now. Being lazy I would like to be able to just add the columns to the join rather than having to rework the relationships and then add the columns.

Disrespect answered 18/3, 2009 at 20:54 Comment(2)
Never? Really? Like never as in "I never use goto"?Registry
I suppose if I could come up with a relationship where it would be logically impossible to add data to it I might choose to go with HABTM. Otherwise, I would go with has_many: through.Disrespect
T
3

I think about it this way. Assuming you've already found that you need a many-to-many model:

X----1
  __/
 /
Y----2
  __/
 /  
Z----3

(x->1 y->1,2 z->2,3)

Use a HABTM relationship if you do NOT need to store information about each of the lines in my (hopefully recognizable) picture above.

If you need to store information about those lines (relationships), then use a "through".

So if you are just saying that people [XYZ] have and belong to projects [123] but do not need to say anything about person X on project 1, use a HABTM.

If you want to say that person X has project 1 and was assigned that project on a given date, you suddenly have a properly for that particular relationship and better use HMT.

Truthful answered 25/5, 2011 at 3:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.