# Has and belongs to many problem

**URL:** <https://www.ruby-forum.com/t/has-and-belongs-to-many-problem/112891>\
**Category:** Rails\
**Created:** [August 24, 2007, 6:01am UTC](https://www.ruby-forum.com/t/has-and-belongs-to-many-problem/112891 "2007-08-24T06:01:37Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![mike](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/58f4c7/32.png) [@mike](https://www.ruby-forum.com/u/mike)\
**Post date:** [August 24, 2007, 6:01am UTC](https://www.ruby-forum.com/t/has-and-belongs-to-many-problem/112891/1 "2007-08-24T06:01:37Z")

</div>

I’m having a problem with a habtm association. I’m not sure if I set  
them up wrong or if I’m trying to work with the models incorrectly.  
Either way I welcome any clarification on why this isn’t working.

My models look like this:

## model/user.rb

class User \< ActiveRecord::Base  
has\_and\_belongs\_to\_many :roles  
[…]  
end

## role/user.rb

class Role \< ActiveRecord::Base  
has\_and\_belongs\_to\_many :users  
end

My migrations look like this:

class CreateUsers \< ActiveRecord::Migration  
def self.up  
create\_table :users do |t|  
t.column :name, :string  
[…]  
end  
end

def self.down  
drop\_table :users  
end  
end

class CreateRoles \< ActiveRecord::Migration  
def self.up  
create\_table :roles do |t|  
t.column :name, :string  
t.column :description, :string  
end  
end

def self.down  
drop\_table :roles  
end  
end

class CreateRolesUsers \< ActiveRecord::Migration  
def self.up  
create\_table :roles\_users do |t|  
t.column :id, :number  
t.column :role\_id, :integer  
t.column :user\_id, :integer  
end  
end

def self.down  
drop\_table :roles\_users  
end  
end

The problem is when I try the following in a migration file I get an  
error:

```
Role.delete_all
superuser = Role.create(
admin = Role.create(
 :name => "Admin"
)
content_editor = Role.create(
 :name => "Content Editor"
)
news_editor = Role.create(
 :name => "News Editor"
)
User.delete_all
michael = User.create(
  :name => "michael",
  :password => "foo"
)
michael.add_roles(admin)
rebecca = User.create(
  :name => "rebecca",
  :password => "foobar"
)
rebecca.add_roles(admin)
rebecca.add_roles(content_editor)
rebecca.add_roles(news_editor)

```

The error is: Mysql::Error: Duplicate entry ‘1’ for key 1: INSERT INTO  
roles\_users (`role_id`, `id`, `user_id`) VALUES (1, 1, 2)

Thanks in advance if you can help me with this.

Peace,  
Mike

---

<div class="post-metadata">

**Author:** ![mike](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/58f4c7/32.png) [@mike](https://www.ruby-forum.com/u/mike)\
**Post date:** [August 24, 2007, 6:28am UTC](https://www.ruby-forum.com/t/has-and-belongs-to-many-problem/112891/2 "2007-08-24T06:28:40Z")

</div>

Is there a reason that you have  
t.column :id, :number  
in the roles\_users table?

---

<div class="post-metadata">

**Author:** ![mike](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/58f4c7/32.png) [@mike](https://www.ruby-forum.com/u/mike)\
**Post date:** [August 24, 2007, 6:55am UTC](https://www.ruby-forum.com/t/has-and-belongs-to-many-problem/112891/3 "2007-08-24T06:55:42Z")

</div>

i’ve been trying a number of things. i originally had no “id” columns  
defined because i didn’t think you needed to create them manually.

---

<div class="post-metadata">

**Author:** ![mike](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/58f4c7/32.png) [@mike](https://www.ruby-forum.com/u/mike)\
**Post date:** [August 24, 2007, 1:54pm UTC](https://www.ruby-forum.com/t/has-and-belongs-to-many-problem/112891/4 "2007-08-24T13:54:43Z")

</div>

On Aug 24, 12:54 am, “Michael Bannister” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> i’ve been trying a number of things. i originally had no “id” columns  
> defined because i didn’t think you needed to create them manually.

Hi Mike. I think you want this:

class CreateRolesUsers \< ActiveRecord::Migration  
def self.up  
create\_table :roles\_users, :id =\> false do |t|  
t.column :role\_id, :integer  
t.column :user\_id, :integer  
end  
end

Essentially, you don’t want to allow ActiveRecord to give your join  
tables an id field which is a primary key. For more information, see  
my post here:

[http://bkocik.net/2007/07/26/habtm-and-the-id-field/](http://bkocik.net/2007/07/26/habtm-and-the-id-field/)
