Has_and_belongs_to_many INSERT duplicate entry


#1

hello folks. please help with the issue:

i got something like this:

class Product < ActiveRecord::Base

has_and_belongs_to_many :groups

def nice_method(x)
self.groups << Group.find(x) <--------------- HERE!
end
end

so… marked line should associate the models, which, if i’m correct,
means: to generate/insert triple (id, product_id, group_id) into table
:groups_products . the issue is, that the the generated id is always
counted from 1, as if the table :groups_products was empty, even if it
isn’t. so i get nice error:

Mysql::Error: Duplicate entry ‘1’ for key 1: INSERT INTO groups_products
(product_id, group_id, id) VALUES (28, 1, 1)

you, journeymans and hackers, tell what the hell is wrong? (i am on
rails 1.2.3)

(i’ve tried also self.group_ids = nice_ids, its the same…)

thanks. fero.


#2

You have a couple of options.

  1. In your database (assumed MySQL) you need to alter the
    groups_products table to have the id field AUTO_INCREMENT:

ALTER TABLE groups_products MODIFY COLUMN id INT(11) AUTO_INCREMENT
PRIMARY KEY;

(Rails migrations actually automatically setup the AUTO_INCREMENT)

  1. For the has_and_belongs_to_many you don’t actually need the “id”
    column. You can do away with that by running:

ALTER TABLE groups_products DROP COLUMN id;

or in your migration you can use:

create_table :groups_products, :id => false do | t |
t.column :groups_id, :integer
t.column :products_id, :integer
end

Good day,
Chris


#3

I don’t see why you have the “nice method” below.

def nice_method(x)
self.groups << Group.find(x) <--------------- HERE!
end

The “.groups <<” is the nice method.


#4

On 5/10/07, Fero removed_email_address@domain.invalid wrote:

def nice_method(x)
self.groups << Group.find(x) <--------------- HERE!
end
end

The HABTM has a :uniq option that is supposed to ignore uniques.

try

class Product < AR::B

has_and_belongs_to_many :uniq => true

def nice_method(x)
self.groups << Group.find(x)
end
end

I think that should take care of the duplicate value for you.

HTH
Daniel


#5

THANKS! the 1) dont work, but 2) is the clear natural solution

The “.groups <<” is the nice method.

its created by has_and_belongs_to_many

again, thanks. fero.


#6

Actually in has_and_belongs_to_many association, the joint table MUST
NOT have an id

in the migration for creating the join table, you need to skip the
default id creation… check the attribute :id for creating table in
the api
http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#M001090

for details
http://blog.modsaid.com/2008/09/hasandbelongstomany-duplicate-entry.html

mahmoud,


#7

Thanks for pointing that out mahmoud

modsaid wrote:

Actually in has_and_belongs_to_many association, the joint table MUST
NOT have an id

in the migration for creating the join table, you need to skip the
default id creation… check the attribute :id for creating table in
the api
http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#M001090

for details
http://blog.modsaid.com/2008/09/hasandbelongstomany-duplicate-entry.html

mahmoud,