# Associations between 3 models

**URL:** <https://www.ruby-forum.com/t/associations-between-3-models/123352>\
**Category:** Rails\
**Created:** [December 16, 2007, 10:05pm UTC](https://www.ruby-forum.com/t/associations-between-3-models/123352 "2007-12-16T22:05:25Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Abhin\_H](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/8e7dd6/32.png) [@Abhin\_H](https://www.ruby-forum.com/u/Abhin_H)\
**Post date:** [December 16, 2007, 10:05pm UTC](https://www.ruby-forum.com/t/associations-between-3-models/123352/1 "2007-12-16T22:05:25Z")

</div>

Hi,

I have this requirement where in the association needs to be  
between 3 models.

I want a User to select a Gift to be sent to a particular  
Destinations.  
For this I created a Model RequestForGift with foreign keys  
( belongs\_to ) to the User, Gift and Destination.Then I added the  
has\_many relationships to each of the 3 Models to the other 2, but  
some how the usage of the association through the models is not  
comforting

class User \< ActiveRecord::Base  
has\_many :RequestForGifts  
has\_many :Gifts, :through =\> :RequestForGifts, :uniq =\> true  
has\_many :Destinations, :through =\> :RequestForGifts, :uniq =\> true  
end

class Gift \< ActiveRecord::Base  
has\_many :RequestForGifts  
has\_many :Users, :through =\> :RequestForGifts, :uniq =\> true  
has\_many :Destinations, :through =\> :RequestForGifts, :uniq =\> true  
end

class Destination \< ActiveRecord::Base  
has\_many :RequestForGifts  
has\_many :Users, :through =\> :RequestForGifts, :uniq =\> true  
has\_many :Destinations, :through =\> :RequestForGifts, :uniq =\> true  
end

class RequestForGift \< ActiveRecord::Base  
belongs\_to :Gift  
belongs\_to :User  
belongs\_to :Destination  
end

i.e. I am not able to find All the Gifts sent by a User to New Delhi,  
India

Basically i am looking for some code like

1. User.find(params[:id]).gifts.select( |g| { g.destination.name =  
‘New Delhi, India’ } )

I know that the same can be achieved by using the RequestForGift  
directly :-

a) destination\_id = Destination.find\_by\_name ( :first, ‘New Delhi,  
India’ )  
RequestForGift.find ( :all, :conditions =\> [ ‘destination\_id = ? and  
user\_id = ?’, destination\_id, params[:id] ] ).collect ( |r| r.gift )  
or  
b) User.find(params[:id]).requestForGifts.select ( |rfg|  
rfg.destination.name = ‘NewDelhi, India’ ).collect ( |rfg| rfg.gift )

But using query a or b would mean that the :has\_many :through  
requirements that I have written will be of no use, since they are  
only double associative - The association assumes that only 2 models  
are involved in the association.

I am facing such models at a really high frequency, and a code  
fragment like query 1, I believe would really mprove  
understandability, of the code since the association table is never  
involved in the ruby code.

Can someone help me out with the model, or if it is even possible with  
the current associations that RoR supports?

Thanks,  
Abhin H

---

<div class="post-metadata">

**Author:** ![Abhin\_H](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/8e7dd6/32.png) [@Abhin\_H](https://www.ruby-forum.com/u/Abhin_H)\
**Post date:** [December 16, 2007, 11:22pm UTC](https://www.ruby-forum.com/t/associations-between-3-models/123352/2 "2007-12-16T23:22:54Z")

</div>

On Dec 16, 3:04 pm, Abhin H [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Hi,
> 
> I have this requirement where in the association needs to be  
> between 3 models.
> 
> I want a User to select a Gift to be sent to a particular  
> Destinations.  
> For this I created a Model RequestForGift

That name will be awkward, since the proper English plural would be  
“RequestsForGifts”. Life will be easier if you change the model name  
to “GiftRequest” and name the table “gift\_requests”.

> with foreign keys  
> ( belongs\_to ) to the User, Gift and Destination.Then I added the  
> has\_many relationships to each of the 3 Models to the other 2, but  
> some how the usage of the association through the models is not  
> comforting
> 
> class User \< ActiveRecord::Base  
> has\_many :RequestForGifts

Relationship names should be in lower case with underscores. If you  
change the model name to “GiftRequest”, then you would have:  
has\_many :gift\_requests  
has\_many :destinations, :through =\> :gift\_requests, :uniq =\> true

There may be similar problems with your table definitions. I would  
write:  
class GiftRequest \< ActiveRecord::Base  
:belongs\_to :user  
:belongs\_to :gift  
:belongs\_to :destination  
…  
end

and in the migration I would have:

add\_table :gift\_requests do |t|  
t.add\_column :user\_id, :integer, :null =\> false  
t.add\_column :gift\_id, …  
t.add\_column :destination\_id, …  
end

---

<div class="post-metadata">

**Author:** ![Abhin\_H](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/8e7dd6/32.png) [@Abhin\_H](https://www.ruby-forum.com/u/Abhin_H)\
**Post date:** [December 17, 2007, 5:06am UTC](https://www.ruby-forum.com/t/associations-between-3-models/123352/3 "2007-12-17T05:06:12Z")

</div>

If it’s any consolation, the trend these days is to make association  
tables into their own models, so perhaps using GiftRequest isn’t so  
“dirty,” after all.

> 1. User.find(params[:id]).gifts.select( |g| { g.destination.name = ‘New Delhi, India’ } )

I don’t think your desired interface would make logical sense in any  
framework, because a gift of a user has more than one destination. I’m  
not sure if there could be an interface that would start from  
User.gifts.

So I’d just bite the bullet, treat GiftRequest as a first-class  
object, and query it directly.

///ark
