# Has\_many or HABTM?

**URL:** <https://www.ruby-forum.com/t/has-many-or-habtm/48976>\
**Category:** Rails\
**Created:** [November 28, 2005, 1:29am UTC](https://www.ruby-forum.com/t/has-many-or-habtm/48976 "2005-11-28T01:29:18Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![i8ramin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/e36b37/32.png) [@i8ramin](https://www.ruby-forum.com/u/i8ramin)\
**Post date:** [November 28, 2005, 1:29am UTC](https://www.ruby-forum.com/t/has-many-or-habtm/48976/1 "2005-11-28T01:29:18Z")

</div>

I can’t determine whether I should be using has\_many or  
has\_and\_belongs\_to\_many. I am creating a community type site with  
users. Users can add other users to their favorites or bookmark them.  
So each user has many favorites. Each favorite is actually another  
User and not another object or model, so I can’t have a  
favorites\_users table. I user model currently looks like this:

class User \< ActiveRecord::Base  
has\_and\_belongs\_to\_many :favorites,  
:join\_table =\> ‘favorites’,  
:class\_name =\> ‘User’,  
:foreign\_key =\> ‘user\_id’,  
:association\_foreign\_key =\> ‘favorite\_id’  
end

and I have a favorites table in my db, defined as:

CREATE TABLE `favorites` (  
`user_id` int(10) NOT NULL default ‘0’,  
`favorite_id` int(10) NOT NULL default ‘0’,  
`created_on` datetime default NULL,  
PRIMARY KEY (`user_id`,`favorite_id`)  
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

Is this correct or can I just use has\_many :favorites?

Thanks

---

<div class="post-metadata">

**Author:** ![i8ramin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/e36b37/32.png) [@i8ramin](https://www.ruby-forum.com/u/i8ramin)\
**Post date:** [November 28, 2005, 1:45am UTC](https://www.ruby-forum.com/t/has-many-or-habtm/48976/2 "2005-11-28T01:45:24Z")

</div>

On 11/28/05, Ramin [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> :join_table => 'favorites',
> 
> ```
> 
> `created_on` datetime default NULL,  
> PRIMARY KEY (`user_id`,`favorite_id`)  
> ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
> 
> Is this correct or can I just use has\_many :favorites?

Take a look at this  
[http://wiki.rubyonrails.com/rails/pages/HowToUseManyToManyAgainstASingleTable](http://wiki.rubyonrails.com/rails/pages/HowToUseManyToManyAgainstASingleTable)

---

<div class="post-metadata">

**Author:** ![i8ramin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/e36b37/32.png) [@i8ramin](https://www.ruby-forum.com/u/i8ramin)\
**Post date:** [November 28, 2005, 1:49am UTC](https://www.ruby-forum.com/t/has-many-or-habtm/48976/3 "2005-11-28T01:49:27Z")

</div>

In all those examples they are using HABTM, so I guess I’m doing it  
right… it works fine enough. I was just wondering if the same thing  
could be done with just has\_many.

On 11/27/05, Rodrigo A. Fernández [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > CREATE TABLE `favorites` (  
> > [Peak Obsession](http://wiki.rubyonrails.com/rails/pages/HowToUseManyToManyAgainstASingleTable)
> 
> * * *
> 
> Rails mailing list  
> removed\_email\_address@domain.invalid  
> [http://lists.rubyonrails.org/mailman/listinfo/rails](http://lists.rubyonrails.org/mailman/listinfo/rails)

–

- Ramin  
[http://www.getintothis.com/blog](http://www.getintothis.com/blog)

---

<div class="post-metadata">

**Author:** ![i8ramin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/e36b37/32.png) [@i8ramin](https://www.ruby-forum.com/u/i8ramin)\
**Post date:** [November 28, 2005, 1:23pm UTC](https://www.ruby-forum.com/t/has-many-or-habtm/48976/4 "2005-11-28T13:23:38Z")

</div>

On 28.11.2005, at 2.47, Ramin wrote:

> In all those examples they are using HABTM, so I guess I’m doing it  
> right… it works fine enough. I was just wondering if the same thing  
> could be done with just has\_many.

Yes, it could, if you’d created a class for favorites. Then you’d  
have two has\_many relationships between user and favorite classes  
(‘favorites’ and ‘people who’ve made me a favorite’).

Of course, if you only need it one way, you’ll be fine with just a  
single relationship.

//jarkko

---

<div class="post-metadata">

**Author:** ![i8ramin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/e36b37/32.png) [@i8ramin](https://www.ruby-forum.com/u/i8ramin)\
**Post date:** [November 28, 2005, 10:14pm UTC](https://www.ruby-forum.com/t/has-many-or-habtm/48976/5 "2005-11-28T22:14:29Z")

</div>

For most things, I’m moving away from HABTM. It is a very nice, simple  
solution in some cases. However, it has limitations and other things  
that make it ‘not-so-nice’ in real usage (sometimes).

You’ll probably find it nice to have an ‘id’ associated with a  
particular favorite. Be it for deleting or otherwise, having this  
explicit is useful to indicate exactly -which- favorite you’re referring  
to.

HABTM works best without this associated ‘id’ and also works best if the  
join table only has two foreign keys and no ancillary data. The docs  
say it could have ancillary data, but the construction isn’t the best –  
ancillary data gets blasted when you use :include to eager load some  
things. (you may want to use ancillary data like a comment that gets  
associated with each favorite or something, but then use eager loading  
to load the other-user’s account group name (or something). Near as I  
can tell, this is broken.

You also gain a few other advantages by defining a new model for your  
favorites. Validations, for example.

Anyway, that’s my take. I still use HABTM, but only in very specific  
cases where all I want is a clean, simple, association.

Jake

i8ramin wrote:

> I can’t determine whether I should be using has\_many or  
> has\_and\_belongs\_to\_many. I am creating a community type site with  
> users. Users can add other users to their favorites or bookmark them.  
> So each user has many favorites. Each favorite is actually another  
> User and not another object or model, so I can’t have a  
> favorites\_users table. I user model currently looks like this:
> 
> class User \< ActiveRecord::Base  
> has\_and\_belongs\_to\_many :favorites,  
> :join\_table =\> ‘favorites’,  
> :class\_name =\> ‘User’,  
> :foreign\_key =\> ‘user\_id’,  
> :association\_foreign\_key =\> ‘favorite\_id’  
> end
> 
> and I have a favorites table in my db, defined as:
> 
> CREATE TABLE `favorites` (  
> `user_id` int(10) NOT NULL default ‘0’,  
> `favorite_id` int(10) NOT NULL default ‘0’,  
> `created_on` datetime default NULL,  
> PRIMARY KEY (`user_id`,`favorite_id`)  
> ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
> 
> Is this correct or can I just use has\_many :favorites?
> 
> Thanks
