Forum: Ruby on Rails has_and_belongs_to_many INSERT duplicate entry

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Fero (Guest)
on 2007-05-09 21:29
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.
Chris (Guest)
on 2007-05-09 21:55
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)

2) 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
Chris (Guest)
on 2007-05-09 21:57
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.
Fero (Guest)
on 2007-05-09 22:14
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.
Daniel -. (Guest)
on 2007-05-10 03:10
(Received via mailing list)
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
modsaid (Guest)
on 2008-09-21 12:56
(Received via mailing list)
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/Co...

for details
http://blog.modsaid.com/2008/09/hasandbelongstoman...

mahmoud,
Tiberiu M. (Guest)
on 2009-05-11 11:12
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/Co...
>
> for details
> http://blog.modsaid.com/2008/09/hasandbelongstoman...
>
> mahmoud,
This topic is locked and can not be replied to.