Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

-clem's avatar
Level 1

How can I define these kinds of relationships in Eloquent?

So I'm trying to make an app that organizes movies and tv. Right now I'm focusing on Movies, but keep in mind the goal is to have a design that can be used for both.

The app should be able to do things like "get the people who acted in this movie", or "get all people who are directors". But people can be actors, directors, writers, producers, and any combination thereof on any number of different movies (and later, tv episodes). So far I've only gotten this functionality by having two models Person and Movie, and then in the database I have tables called actors, directors, writers. Each of these tables has only the fields person_id and movie_id, so they look like pivot tables but aren't actually used as such (red flag #1). Instead, the concept of "what this person did on this movie" is abstracted away into Controllers that do subqueries on these pivot-but-not-really tables. So my routes file looks like this:

Route::get('/movies', 'MovieController@index');
Route::get('/movies/{id}/actors', 'MovieActorsController@index');
Route::get('/movies/{id}/directors', 'MovieDirectorsController@index');
Route::get('/people', 'PersonController@index');
Route::get('/actors', 'ActorController@index');
Route::get('/directors', 'DirectorController@index');

And the controllers look like this:

class MovieActorsController extends Controller
{
    // Get people who acted in the specified movie
    public function index($id)
    {
        return Person::whereIn('id', function($sub) use($id) {
            $sub->select('person_id')->from('actors')->where('movie_id', $id);
        })->get();
    }
}

Obviously I really want these relationships to actually exist in the database, and in my app as Eloquent models. Maybe we have a Credit model, and each Person and Movie model can have many Credits. But each Credit can be one of any different kinds like ActingCredit, DirectingCredit, etc. I've read the Eloquent docs and a lot of blog posts/forum comments, and I keep feeling like I'm getting closer but not quite there. I think the answer lies in custom Pivot table Models and/or polymorphism but I'm hitting a mental roadblock as to how to actually implement them.

Any help -- even just terms and phrases to google -- would be greatly appreciated. Thanks!

Edit: If it's not clear what problem I am trying to solve, please see my later reply here https://laracasts.com/discuss/channels/eloquent/how-can-i-define-these-kinds-of-relationships-in-eloquent?page=1#reply=541470

0 likes
6 replies
jlrdw's avatar

Well an actor could have directed also. So use polymorphism where necessary, but there are times where a checkbox thus storing a 0 or 1 in database also works.

There are movies where the person wrote, acted, directed, and produced the movie.

acted  | 1
direct  | 0

Just some thoughts on it.

I think imdb has an api. It might give you some ideas.

lacasera's avatar

why don't you create a movies and crew_members table, then on the crew table, there will be a role filed that will represent the role of that crew member. eg. actor, director, producer etc. you then can define a many-to-many relationship between the movies and the crew_members table since a crew member may belong to other movies

class Movie extends Model
{

    public function crew_members()
    {
        return $this->belongsToMany(App\CrewMember::class);
    }

}
class CrewMember extends Model
{


    public function movies()
    {
        return $this->belongsToMany(App\Movies::class);
    }
}

Then you can do

$movie = App\Movies::find(1);

// all crew members
$movie->crew_members;


$comment = App\Post::find(1)->comments()->where('title', 'foo')->first();

// only producers

$producers = App\Movie::find(1)->crew_members()->where('role', 'producer')->get()
lacasera's avatar

however because one crew member may have multiple roles on a single or multiple movies, it will be wise to have a separate table just for the roles and define that relationship on the crew_members table. So your CrewMember model ends up looking like this

class CrewMember extends Model
{


        public function movies()
        {
            return $this->belongsToMany(App\Movies::class);
    }

     public function roles()
    {
        return $this->hasMany(App\Roles::class)
    }
}

you can then get the crew members with their roles on a movie with

$movie = App\Movie::with('crew_members.roles`)->find(1);
lacasera's avatar

@-clem kindly explain your last post. not sure I get what you mean

lacasera's avatar

@-clem I think the eventual duplication of records is the flaw in the design you are proposing. I think this the best I can come up with. good luck and happy hacking.

lacasera's avatar

But in my head, a Movie has relationships not with Persons, but with actors and directors. But you know actors and directors in the end are all Persons in a way. so no matter how you want to structure your db, an actor or director who is a person will have a relationship with a movie.

Please or to participate in this conversation.