# How to define people and movies' association?

**URL:** <https://www.ruby-forum.com/t/how-to-define-people-and-movies-association/114536>\
**Category:** Rails\
**Created:** [September 14, 2007, 10:34am UTC](https://www.ruby-forum.com/t/how-to-define-people-and-movies-association/114536 "2007-09-14T10:34:58Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![xain](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/x/82dd89/32.png) [@xain](https://www.ruby-forum.com/u/xain)\
**Post date:** [September 14, 2007, 10:34am UTC](https://www.ruby-forum.com/t/how-to-define-people-and-movies-association/114536/1 "2007-09-14T10:34:58Z")

</div>

I want to make a app similar to [www.imdb.com](http://www.imdb.com), now I have a problem to  
define the association of two table --people and movies .  
Movie stars, movie writers… are allow people, I plan to put all people  
data into one table named “people”, and I’ll use “movies” table to store  
movies’ information. A movie may have none or more than one movie  
writer/ movie star information, and a movie star may show up on several  
movies.

I want to make association between people table and movies, in such a  
way that I can list all movie stars who shown on one movie with  
movie.movie\_stars, and writers with movie.writers, while  
movie.movie\_writers \<\< person will add a movie writer info.

Here’s my current idea:  
A third table,named “movies\_people”, containing movie\_id, person\_id,  
char\_type columns, is to be added. char\_type column is used to store  
person’s role in the movie, like “movie\_star” to identify the person is  
added as a movie star.

MoviesPeople Class

> belongs\_to :movie  
> belongs\_to :person

Movie Class

> has\_many :movies\_people

Person Class

> has\_many :person

Add methods to Movie.rb, like:

> def movie\_stars  
> Person.find(movies\_people.find\_by\_char\_type(“movie\_star”).collect{|o| o.person\_id})  
> end

The question is: is that a good idea, or there are better ones?

---

<div class="post-metadata">

**Author:** ![xain](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/x/82dd89/32.png) [@xain](https://www.ruby-forum.com/u/xain)\
**Post date:** [September 14, 2007, 3:41pm UTC](https://www.ruby-forum.com/t/how-to-define-people-and-movies-association/114536/2 "2007-09-14T15:41:44Z")

</div>

How about a roles table?

Class Rol \< AR::Base  
has\_many :participations  
has\_many :people, :through =\> :participations  
end

Class Person \< AR::Base  
has\_many :participations  
has\_many :movies, :through =\> :participations  
has\_many :roles, :through =\> :participations  
end

Class Participation \< AR::Base  
belongs\_to :rol  
belongs\_to :person  
belongs\_to :movie  
end

Class Movie \< AR::Base  
has\_many :participations  
has\_many :persons, :through =\> :participations  
end

ie  
Person.participations =\> may bring an array of participation objects,  
like

[[person, movie, rol], …] =\> [[“John”, “A Movie”, “Actor”], [“John”,  
“Another Movie”, “Director”], …]

Person.movies returns all the movies of the person.

Rol.find\_by\_name(“Actors”).people =\> Return all the persons that have  
record on partipation in the role of actor.

THE PROBLEM: With this system you can’t assign a person a rol if it has  
not acted in a movie sometime, ie: you can’t know if a person is an  
actor until he actually acts in a movie!. You could add another table to  
state the people =\> rol relationship, even if they have not participated  
yet on a movie:

make a table people\_roles =\> person\_id, rol\_id, whitout an ActiveRecord  
class, and add add:

has\_and\_belongs\_to\_many :roles to class People and  
has\_and\_belongs\_to\_many :people to class Rol

YES! it’s a messy response to a messy problem 🙂

---

<div class="post-metadata">

**Author:** ![xain](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/x/82dd89/32.png) [@xain](https://www.ruby-forum.com/u/xain)\
**Post date:** [September 14, 2007, 5:27pm UTC](https://www.ruby-forum.com/t/how-to-define-people-and-movies-association/114536/3 "2007-09-14T17:27:27Z")

</div>

Nanyang Z. wrote:

> Here’s my current idea:  
> A third table,named “movies\_people”, containing movie\_id, person\_id,  
> char\_type columns, is to be added. char\_type column is used to store  
> person’s role in the movie, like “movie\_star” to identify the person is  
> added as a movie star.
> 
> MoviesPeople Class
> 
> > belongs\_to :movie  
> > belongs\_to :person
> 
> Movie Class
> 
> > has\_many :movies\_people
> 
> Person Class
> 
> > has\_many :person
> 
> Add methods to Movie.rb, like:
> 
> > def movie\_stars  
> > Person.find(movies\_people.find\_by\_char\_type(“movie\_star”).collect{|o| o.person\_id})  
> > end
> 
> The question is: is that a good idea, or there are better ones?

A movie has many people and a person belongs to a movie, or you could do  
a HABTM association so a movie has and belongs to many people and a  
person has and belongs to many movies.

~Jeremy

---

<div class="post-metadata">

**Author:** ![xain](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/x/82dd89/32.png) [@xain](https://www.ruby-forum.com/u/xain)\
**Post date:** [September 14, 2007, 6:22pm UTC](https://www.ruby-forum.com/t/how-to-define-people-and-movies-association/114536/4 "2007-09-14T18:22:08Z")

</div>

Jeremy W. wrote:

> a HABTM association so a movie has and belongs to many people and a  
> person has and belongs to many movies.

A habtm association can not tell the role of one person that  
participated for the movie.

---

<div class="post-metadata">

**Author:** ![xain](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/x/82dd89/32.png) [@xain](https://www.ruby-forum.com/u/xain)\
**Post date:** [September 14, 2007, 6:19pm UTC](https://www.ruby-forum.com/t/how-to-define-people-and-movies-association/114536/5 "2007-09-14T18:19:37Z")

</div>

Emmanuel O. wrote:

> How about a roles table?

> Class Participation \< AR::Base  
> belongs\_to :rol  
> belongs\_to :person  
> belongs\_to :movie  
> end

A participation model! It sounds attractive.With this model, the  
relation of people and movies is clearer.

> ie  
> Person.participations =\> may bring an array of participation objects,  
> like
> 
> [[person, movie, rol], …] =\> [[“John”, “A Movie”, “Actor”], [“John”,  
> “Another Movie”, “Director”], …]
> 
> Person.movies returns all the movies of the person.  
> Good. But it seems all the favors go to the people part. How to make  
> movie.actors show all the actors of one movie?

> THE PROBLEM: With this system you can’t assign a person a rol if it has  
> not acted in a movie sometime, ie: you can’t know if a person is an  
> actor until he actually acts in a movie!.

Then, just let it be. Maybe people wouldn’t notice an actor without an  
movie.

> make a table people\_roles =\> person\_id, rol\_id, whitout an ActiveRecord  
> class, and add add:
> 
> has\_and\_belongs\_to\_many :roles to class People and  
> has\_and\_belongs\_to\_many :people to class Rol

…All sounds good, except one thing:I came here looking for a simple  
solution.
