# Simple has\_many :through question

**URL:** <https://www.ruby-forum.com/t/simple-has-many-through-question/123689>\
**Category:** Rails\
**Created:** [December 19, 2007, 7:57pm UTC](https://www.ruby-forum.com/t/simple-has-many-through-question/123689 "2007-12-19T19:57:48Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![JonathanB](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8e8cbc/32.png) [@JonathanB](https://www.ruby-forum.com/u/JonathanB)\
**Post date:** [December 19, 2007, 7:57pm UTC](https://www.ruby-forum.com/t/simple-has-many-through-question/123689/1 "2007-12-19T19:57:48Z")

</div>

Ok, I have 2 very simple has\_many :through associations I need to  
create and, despite bashing my brain and my computer against this  
problem repeatedly for 2 days, I cannot figure out what I am doing  
wrong as I cannot get the has\_many :through to work. I think I have  
fundamentally misunderstood how to do has\_many :throughs, so I am  
going to ruby script/destroy the models I have created and try again.  
I’m going to post here my steps to create these relationship, can  
someone please let me know if I’m doing this correctly? First, the  
relationships.

Contacts \<== Account\_Contacts ==\> Account \<== Account\_Attachments ==\>  
Attachments

the 2 word tables are the join tables, basically Contacts and  
Attachments have a many to many relationship with Account.

1. ruby script/generate model Account
2. ruby script/generate model Contact
3. ruby script/generate model Attachment
4. fill in migration file for the account table (no need to reference  
a join table here)
5. fill in migration file for the contact table (here I am creating  
the Account\_Contacts table with integer fields for Account and  
Contact, as well as a category field)
6. fill in migration file for the attachment table (Same as the  
contact table, I create Account\_Attachments here with the same  
fields).
7. rake db:migrate

Ok, now I should have a functioning has\_many :through relationship,  
right? When I attempted to use this relationship in the console like  
so:

acct = Account.find(1)  
file = Attachment.find(1)  
acct.attachments.create( :attachment =\> file, :category =\> “test”)

I get the following error message:

NameError: uninitialized constant Account::AccountAttachment  
from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/  
activesupport-1.4.2/lib  
/active\_support/dependencies.rb:477:in `const_missing' from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/ activerecord-1.15.3/lib /active_record/base.rb:1360:in`compute\_type’  
from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/  
activerecord-1.15.3/lib  
/active\_record/reflection.rb:125:in `send' from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/ activerecord-1.15.3/lib /active_record/reflection.rb:125:in`klass’  
from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/  
activerecord-1.15.3/lib  
/active\_record/reflection.rb:177:in `source_reflection' from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/ activerecord-1.15.3/lib /active_record/reflection.rb:177:in`collect’  
from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/  
activerecord-1.15.3/lib  
/active\_record/reflection.rb:177:in `source_reflection' from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/ activerecord-1.15.3/lib /active_record/reflection.rb:186:in`check\_validity!’  
from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/  
activerecord-1.15.3/lib  
/active\_record/associations/has\_many\_through\_association.rb:6:in  
`initialize' from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/ activerecord-1.15.3/lib /active_record/associations.rb:934:in`new’  
from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/  
activerecord-1.15.3/lib  
/active\_record/associations.rb:934:in `attachments’  
from (irb):3

What did I do wrong here?

---

<div class="post-metadata">

**Author:** ![JonathanB](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8e8cbc/32.png) [@JonathanB](https://www.ruby-forum.com/u/JonathanB)\
**Post date:** [December 19, 2007, 8:27pm UTC](https://www.ruby-forum.com/t/simple-has-many-through-question/123689/2 "2007-12-19T20:27:50Z")

</div>

On Dec 19, 2007, at 12:57 PM, JonathanB wrote:

> Ok, now I should have a functioning has\_many :through relationship,  
> right? When I attempted to use this relationship in the console like  
> so:

You need to edit the models and add something like

contacts.rb  
has\_many :account\_contacts  
has\_many :accounts, :through =\> :account\_contacts

account.rb  
has\_many :account\_contacts  
has\_many :contacts, :though =\> :account\_contacts  
has\_many :account\_attachments  
has\_many :attachments, :through =\> :account\_attachments

Peace,  
Phillip

---

<div class="post-metadata">

**Author:** ![JonathanB](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8e8cbc/32.png) [@JonathanB](https://www.ruby-forum.com/u/JonathanB)\
**Post date:** [December 19, 2007, 9:16pm UTC](https://www.ruby-forum.com/t/simple-has-many-through-question/123689/3 "2007-12-19T21:16:54Z")

</div>

On Dec 19, 2007, at 2:05 PM, gemblon (t.b.) wrote:

> Phillip has a really NICE Short version.  
> here is a longer version, if you are interested.
> 
> * * *

Not just longer ;), but actually correct. I forgot the join table  
models that have the :belongs\_to. I don’t think it would have worked  
without that!

Thanks gemblon!

Peace,  
Phillip

---

<div class="post-metadata">

**Author:** ![JonathanB](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8e8cbc/32.png) [@JonathanB](https://www.ruby-forum.com/u/JonathanB)\
**Post date:** [December 19, 2007, 9:05pm UTC](https://www.ruby-forum.com/t/simple-has-many-through-question/123689/4 "2007-12-19T21:05:45Z")

</div>

Phillip K. wrote:

> On Dec 19, 2007, at 12:57 PM, JonathanB wrote:
> 
> contacts.rb  
> has\_many :account\_contacts  
> has\_many :accounts, :through =\> :account\_contacts
> 
> account.rb  
> has\_many :account\_contacts  
> has\_many :contacts, :though =\> :account\_contacts  
> has\_many :account\_attachments  
> has\_many :attachments, :through =\> :account\_attachments
> 
> Peace,  
> Phillip

Phillip has a really NICE Short version.  
here is a longer version, if you are interested.

* * *

OLD WAY - has\_and\_belongs\_to\_many :my\_model

```
This is an out of date technique to set up the many-to-many table. A 

```

major limitation to this method is that you cannot have any more fields  
in the table then the 2 joining fields, and the join table does not use  
a primary field key called â€˜idâ€™. You canâ€™t sort joined fields very  
easily with this method.

```
This technique is very easy to set up. The table name is the plural 

```

names of the 2 joining tables, in alphabetical order, separated by an  
underscore. Table C and B would be BS\_CS. The only 2 fields in the join  
table would be b\_id and c\_id.

NEW WAY - has\_many :through

```
This technique allows the join table to have as many fields as you 

```

want. You need a model, for the joining, to make this work. You can just  
generate a model. But if you need more fields, you can scaffold. The  
join table also gets the primary key field (â€™idâ€™) that is automatically  
generated in most cases.

```
The joining table can be named what ever you want. The current trend 

```

is to use a table name that just has one word, and usually ends in  
-ship, -tion, or -ment. There can be endless hours of debate over the  
name of the joining table.

```
You will need to have the 2 joining tableâ€™s foreign key fields in 

```

this table, like the fashion â€˜\_idâ€™, that are not pluralized.

```
If you wanted to join table A and table B, an example of the joining 

```

table could be:

```
TABLES

    A

        id (integer, primary key)
        name (string)

    B

        id (integer, primary key)
        name (string)

    AB (many table for joining tables A and B)

        id (integer, primary key)
        a_id (integer)
        b_id (integer)
        â€¦ (more fields)

The MODELS

    A

        has_many :ABs
        has_many :Bs :through => :ABs

    AB

        belongs_to :A
        belongs_to :B

    B

        has_many :ABs
        has_many :As :through => :ABs

SOME OPTIONS

    has_many :mytable, :foreign_key => 'myfield_id',
                           :class_name => 'myclassname',
                           :dependent => :destroy
```
