Has_many or HABTM?


#1

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


#2

On 11/28/05, Ramin 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


#3

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 wrote:

CREATE TABLE favorites (
http://wiki.rubyonrails.com/rails/pages/HowToUseManyToManyAgainstASingleTable


Rails mailing list
removed_email_address@domain.invalid
http://lists.rubyonrails.org/mailman/listinfo/rails


#4

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


#5

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