# A Model Belongs to Many Model

**URL:** <https://www.ruby-forum.com/t/a-model-belongs-to-many-model/136871>\
**Category:** Rails\
**Created:** [May 7, 2008, 12:57am UTC](https://www.ruby-forum.com/t/a-model-belongs-to-many-model/136871 "2008-05-07T00:57:15Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![baros119](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/65b543/32.png) [@baros119](https://www.ruby-forum.com/u/baros119)\
**Post date:** [May 7, 2008, 12:57am UTC](https://www.ruby-forum.com/t/a-model-belongs-to-many-model/136871/1 "2008-05-07T00:57:15Z")

</div>

Hi,

I have a design question. I have 4 models, Photo, Trip, Destination, and  
Hotel. I want Trip, Destination, and Hotel to have Photos. A Photo  
always belongs to a Destination but at the same time it can belongs to  
Trip and Hotel. Most of the time a Photo belongs to Trip & Destination.  
The way I have it right now is the following:

```auto
class Trip < ActiveRecord::Base
  :has_many :photos

class Destination < ActiveRecord::Base
  :has_many :photos

class Hotel < ActiveRecord::Base
  :has_many :photos

class Photos < ActiveRecord::Base
  :belongs_to :trip
  :belongs_to :destination
  :belongs_to :hotel
```

photos table will have trip\_id, destination\_id, and hotel\_id. And since  
a record in photo table doesn’t always belongs to trip or hotel, trip\_id  
and hotel\_id can be null. That’s should be ok right to have null in the  
foreign key? Is this the best way to do it or there’s a better design to  
this problem? Moreover, I want to be able to easily add another model  
that I can attach photos to it.

Thanks!

---

<div class="post-metadata">

**Author:** ![baros119](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/65b543/32.png) [@baros119](https://www.ruby-forum.com/u/baros119)\
**Post date:** [May 7, 2008, 1:20am UTC](https://www.ruby-forum.com/t/a-model-belongs-to-many-model/136871/2 "2008-05-07T01:20:10Z")

</div>

On 6 May 2008, at 23:57, Fajar A b wrote:

> photos table will have trip\_id, destination\_id, and hotel\_id. And  
> since  
> a record in photo table doesn’t always belongs to trip or hotel,  
> trip\_id  
> and hotel\_id can be null. That’s should be ok right to have null in  
> the  
> foreign key?  
> Unless you’ve explicitly asked for it not to be null

> Is this the best way to do it or there’s a better design to  
> this problem? Moreover, I want to be able to easily add another model  
> that I can attach photos to it.

You may be interested in a polymorphic association:  
make photos have columns subject\_id, and subject\_type.  
then  
class Photo \< ActiveRecord::Base  
belongs\_to :subject, :polymorphic =\> true  
end

class Trip \< AR::Base  
has\_many :photos, :as =\> :subject  
end

class Destination \< AR::Base  
has\_many :photos, :as =\> :subject  
end

etc…

photo.subject will return an instance of the appropriate class.

Fred

---

<div class="post-metadata">

**Author:** ![baros119](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/65b543/32.png) [@baros119](https://www.ruby-forum.com/u/baros119)\
**Post date:** [May 7, 2008, 4:14am UTC](https://www.ruby-forum.com/t/a-model-belongs-to-many-model/136871/3 "2008-05-07T04:14:45Z")

</div>

Frederick C. wrote:

> On 6 May 2008, at 23:57, Fajar A b wrote:
> 
> > photos table will have trip\_id, destination\_id, and hotel\_id. And  
> > since  
> > a record in photo table doesn’t always belongs to trip or hotel,  
> > trip\_id  
> > and hotel\_id can be null. That’s should be ok right to have null in  
> > the  
> > foreign key?  
> > Unless you’ve explicitly asked for it not to be null
> 
> > Is this the best way to do it or there’s a better design to  
> > this problem? Moreover, I want to be able to easily add another model  
> > that I can attach photos to it.
> 
> You may be interested in a polymorphic association:  
> make photos have columns subject\_id, and subject\_type.  
> then  
> class Photo \< ActiveRecord::Base  
> belongs\_to :subject, :polymorphic =\> true  
> end
> 
> class Trip \< AR::Base  
> has\_many :photos, :as =\> :subject  
> end
> 
> class Destination \< AR::Base  
> has\_many :photos, :as =\> :subject  
> end
> 
> etc…
> 
> photo.subject will return an instance of the appropriate class.
> 
> Fred

Thanks for the reply Fred. I’d like to be able to do destination.photos  
which will returns all photos that belongs to destination. Can I do this  
with polymorphic? What I understand is when I use your setup and do  
destination.photos it will only return photos that has subject\_type =  
“Destination”. SOme photos belong to a trip and also a destination.

Thanks!

---

<div class="post-metadata">

**Author:** ![baros119](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/65b543/32.png) [@baros119](https://www.ruby-forum.com/u/baros119)\
**Post date:** [May 7, 2008, 10:39am UTC](https://www.ruby-forum.com/t/a-model-belongs-to-many-model/136871/4 "2008-05-07T10:39:57Z")

</div>

On 7 May 2008, at 03:14, Fajar A b wrote:

> > 
> 
> Thanks for the reply Fred. I’d like to be able to do  
> destination.photos  
> which will returns all photos that belongs to destination. Can I do  
> this  
> with polymorphic? What I understand is when I use your setup and do  
> destination.photos it will only return photos that has subject\_type =  
> “Destination”. SOme photos belong to a trip and also a destination.

Oops, I’d glossed over the fact that some photos belong to more than  
one of destination/trip/etc…  
Perhaps a has\_many :through, where the association to destination/trip/  
etc on the join table is polymorphic ?

Fred

---

<div class="post-metadata">

**Author:** ![baros119](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/65b543/32.png) [@baros119](https://www.ruby-forum.com/u/baros119)\
**Post date:** [May 9, 2008, 10:47am UTC](https://www.ruby-forum.com/t/a-model-belongs-to-many-model/136871/5 "2008-05-09T10:47:20Z")

</div>

Frederick C. wrote:

> On 7 May 2008, at 03:14, Fajar A b wrote:
> 
> > > 
> > 
> > Thanks for the reply Fred. I’d like to be able to do  
> > destination.photos  
> > which will returns all photos that belongs to destination. Can I do  
> > this  
> > with polymorphic? What I understand is when I use your setup and do  
> > destination.photos it will only return photos that has subject\_type =  
> > “Destination”. SOme photos belong to a trip and also a destination.
> 
> Oops, I’d glossed over the fact that some photos belong to more than  
> one of destination/trip/etc…  
> Perhaps a has\_many :through, where the association to destination/trip/  
> etc on the join table is polymorphic ?
> 
> Fred

This is what I ended up doing:

class Photo \< ActiveRecord::Base  
belongs\_to :user  
belongs\_to :destination  
belongs\_to :content, :polymorphic =\> true

class Destination \< ActiveRecord::Base  
has\_many :photos

class Trip \< ActiveRecord::Base  
belongs\_to :user  
belongs\_to :destination

This way I can do destination.photos and get all photos for that  
destination even though the content is Trip or anything else. What do  
you guys think?

Andrew,  
Destination usually a city and hotel must belongs to a destination.

---

<div class="post-metadata">

**Author:** ![baros119](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/65b543/32.png) [@baros119](https://www.ruby-forum.com/u/baros119)\
**Post date:** [May 7, 2008, 9:29am UTC](https://www.ruby-forum.com/t/a-model-belongs-to-many-model/136871/6 "2008-05-07T09:29:34Z")

</div>

Fajar A b wrote:

> Thanks for the reply Fred. I’d like to be able to do destination.photos  
> which will returns all photos that belongs to destination. Can I do this  
> with polymorphic? What I understand is when I use your setup and do  
> destination.photos it will only return photos that has subject\_type =  
> “Destination”. SOme photos belong to a trip and also a destination.
> 
> Thanks!

Polymorphics are certainly the way to go here. Once you understand them  
you will use them everywhere 🙂

If you declare the associations as Fred described you will be able to  
call destination.photos, which will return an array of photo objects.

You are also correct about one photo belonging to one model. However,  
are you sure that photos really need to belong to destinations, trips,  
and hotels or would it be better attaching photos to one, then using the  
associations to pull them back again?

(as an aside, I am a little confused about the difference between a  
destination and a hotel. Surely a hotel is one kind of destination?)

---

<div class="post-metadata">

**Author:** ![baros119](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/65b543/32.png) [@baros119](https://www.ruby-forum.com/u/baros119)\
**Post date:** [May 9, 2008, 12:10pm UTC](https://www.ruby-forum.com/t/a-model-belongs-to-many-model/136871/7 "2008-05-09T12:10:50Z")

</div>

Fajar A b wrote:

> This is what I ended up doing:
> 
> class Photo \< ActiveRecord::Base  
> belongs\_to :user  
> belongs\_to :destination  
> belongs\_to :content, :polymorphic =\> true
> 
> class Destination \< ActiveRecord::Base  
> has\_many :photos
> 
> class Trip \< ActiveRecord::Base  
> belongs\_to :user  
> belongs\_to :destination
> 
> This way I can do destination.photos and get all photos for that  
> destination even though the content is Trip or anything else. What do  
> you guys think?
> 
> Andrew,  
> Destination usually a city and hotel must belongs to a destination.

I must be missing something here - where is “has\_many :photos, :as =\>  
:content” used?

Looks like your on the right track, but let me have a crack (without  
fully understanding your requirements).

We have a few moving parts - users, photos, destinations, and trips. A  
user wants to plan their holiday by building up a series of destinations  
into a trip. They may want to look at photos of their destinations to  
choose good looking hotels to stay at. Users can also upload photos of  
destinations they have visited for others to look at. Given this, the  
models would look something like:

class User \< ActiveRecord::Base  
has\_many :trips  
has\_many :photos  
has\_many :destinations, :through =\> :trips  
end

class Trip \< ActiveRecord::Base  
belongs\_to :user  
has\_many :destinations  
has\_many :photos, :through =\> :destinations # Is this useful?  
end

class Destination::ActiveRecord::Base  
belongs\_to :trip  
has\_many :photos, :as =\> photographable  
has\_many :users, :through =\> trips # So we can look up users who have  
been here.  
end

class Photo \< ActiveRecord::Base  
belongs\_to :user  
belongs\_to :destination  
has\_many :trips, :through =\> :destinations # Not sure if this works  
belongs\_to :photographable, :polymorphic =\> true  
end

Now you can call the following in your controllers/views:

user.trips # List all the trips a user has created  
user.photos # List all the photos a user has uploaded  
trip.destinations # List the destinations associated with a trip  
destination.photos # List all the photos for a given destination  
trip.photos # Grab all the photos attached to all the  
destinations in this trip

etc.
