HABTM << Behavior

Lets say you have a relationship like post has and belongs to many
categories. If I were to do something like the following:

category << post
category << post
category << post

I’ve basically assigned the post to the category three times. I’m
noticing that in my join table there are now three join records?
Shouldn’t it only have one?

This causes problems when you do category.posts and you get the same
post three times. I’m just wondering if I am missing something here?


On 5 Nov 2008, at 23:01, TomRossi7 wrote:

Shouldn’t it only have one?
If that’s what you require, set the :uniq option on the association
(and create a unique index on that table to enforce that if you are so



Thanks for the reply! The :uniq is good work around, but multiple
entries are still added to the database. The unique index will
actually cause ActiveRecord to throw an error since it is trying to
create a duplicate record.

This seems like a bug to me that it creates duplicate records? I can
code around it, but wanted to make sure I wasn’t missing something.


On Nov 6, 5:21 am, Frederick C. [email protected]

On 6 Nov 2008, at 14:00, TomRossi7 wrote:

I don’t think it’s necessarily a bug. Depend on how you are using it
duplicate records in an association might be allowed, or might not,
it’s not the frameworks job to say ‘collections shall have no
duplicates’. I’m slightly surprised that uniq only affects reading
from the collection, I suppose the thing is that normally categories
<< post does not require loading the collection whereas if it checked
if categories.include?(post) that would force the collection to be
loaded (at least it would have previously - I seem to recall the
include? no longer causes the collection to be loaded)



Yeah, you are totally tracking with what I am saying. I think it is a
bug though because in a 1 to many relationship, or in a many to many
relationship, the same join shouldn’t exist more than once? Is there
a scenario where it even makes sense?

The :uniq option just has ruby remove duplicates from the array
returned (e.g. category.posts.uniq). The categories.include?(post)
code around is the one I am going with, its just not as elegant as I
was hoping for. Now I just need to do a comparison to see if the
child has already been assigned to the parent before adding it.


On Nov 6, 9:37 am, Frederick C. [email protected]