title: Laravel many to many: Movie - Person - Role
body: <p>Would like to have models &amp; relationships where I have:</p>
  
  <ul>
  <li>movies</li>
  <li>persons</li>
  <li>roles (director, script, actor, etc.)</li>
  </ul>
  
  <p>If it is just movies &amp; persons I could set up a <a href="https://laravel.com/docs/master/eloquent-relationships#many-to-many" rel="nofollow noreferrer">many-to-many relationship</a> (create <code>person_role</code> migration and add <code>$this-&gt;belongsToMany()</code> to both Person and Role models)<br>
  However: person X can be an <strong>actor</strong> in movie A and be both <strong>actor</strong> and <strong>director</strong> in movie B.<br>
  I saw the <a href="https://stackoverflow.com/questions/59493407/many-to-many-relationships-movie-role-actor">Django answer</a>, but not sure how this is done in Laravel. (update: the Django answer refers to "role" being the name of the character. In my case: role = actor/director/writer/...)  </p>
  
  <p><strong>Update</strong>: more details of the environment and my attempts.</p>
  
  <p>I created movies, persons, roles and the lookup table movie_person_role (aka triple pivot):</p>
  
  <pre><code>movies
  - id
  - name
  
  persons
  - id
  - name
  
  roles
  - id
  - name [director, script, actor, etc.]
  
  movie_person_role
  - id
  - foreignId: movie_id
  - foreignId: person_id
  - foreignId: role_id
  </code></pre>
  
  <p>method:</p>
  
  <pre><code>class Movie extends Model
  {
      public function persons() {
          return $this-&gt;belongsToMany('App\Person', 'movie_person_role', 'movie_id', 'person_id')-&gt;withPivot('role_id');
      }
  
      public function roles() {
          return $this-&gt;belongsToMany('App\Role', 'movie_person_role', 'movie_id', 'role_id')-&gt;withPivot('person_id');
      }
  }
  </code></pre>
  
  <p>seeder:</p>
  
  <pre><code>        $id = DB::table('movies')-&gt;insertGetId([
              'name' =&gt; 'Redbad',
          ]);
          $m = App\Movies::find($id);
          $w-&gt;persons()-&gt;attach([
              App\Person::name('Roel Reiné')-&gt;first()-&gt;id =&gt; ['role_id' =&gt; App\Role::name('director')-&gt;first()-&gt;id],
              App\Person::name('Alex van Galen')-&gt;first()-&gt;id =&gt; ['role_id' =&gt; App\Role::name('writer')-&gt;first()-&gt;id],
              App\Person::name('Jonathan Banks')-&gt;first()-&gt;id =&gt; ['role_id' =&gt; App\Role::name('actor')-&gt;first()-&gt;id],
          ])
  
  </code></pre>
  
  <p>(could be there are cleaner ways of defining the seeds)</p>
  
  <p>This correctly links e.g. <code>person</code> "Roel Reiné" as <code>role</code> "director" to <code>movie</code> "Redbad".</p>
  
  <p>What remains: how to get list of persons + roles for a movie?</p>
  
  <p>Status at the moment is that I can get the persons (without their role):</p>
  
  <p>tinker:</p>
  
  <pre><code>&gt;&gt;&gt; App\Movie::where('title','Redbad')-&gt;with('persons')-&gt;get()
  =&gt; Illuminate\Database\Eloquent\Collection {#3204
       all: [
         App\Work {#3224
           id: 1,
           name: "Redbad",
           persons: Illuminate\Database\Eloquent\Collection {#3179
             all: [
               App\Person {#3250
                 id: 2,
                 name: "Roel Reiné",
                 pivot: Illuminate\Database\Eloquent\Relations\Pivot {#3249
                   movie_id: 1,
                   person_id: 2,
                   role_id: 1,
                 },
               },
      ...
  </code></pre>
  
  <p>This gives the Persons involved in the Redbad movie. And in the pivot object I see the role id.<br>
  It allows me to do queries like <code>$movie-&gt;persons()-&gt;where('role_id',4)-&gt;get()</code> which gives me all the <code>actors</code> for a specific movie or `</p>
  
  <p>But I would prefer eager loading of the role, just like the person, so that I can easily create a list of movies, with the persons and their role. E.g.</p>
  
  <pre><code>movie A - person K - role director
  movie A - person L - role director
  movie A - person L - role actor
  movie B - person M - role director
  movie B - person N - role actor
  </code></pre>