Laravel много ко многим: Mov ie - Человек - Роль - PullRequest
0 голосов
/ 12 марта 2020

Хотелось бы иметь модели и отношения, где у меня есть:

  • фильмы
  • персонажи
  • роли (режиссер, сценарий, актер и т. Д. c). )

Если бы это были только фильмы и люди, я мог бы установить отношение «многие ко многим» (создать миграцию person_role и добавить $this->belongsToMany() к человеку и роли модели)
Однако: человек X может быть актером в mov ie A и быть одновременно актером и режиссером в mov ie B.
Я видел Django ответ , но не уверен, как это сделать в Laravel. (обновление: ответ Django относится к «роли», являющейся именем персонажа. В моем случае: роль = актер / режиссер / писатель / ...)

Обновление : более подробная информация об окружении и моих попытках.

Я создал фильмы, людей, роли и справочную таблицу

сеялка:

        $id = DB::table('movies')->insertGetId([
            'name' => 'Redbad',
        ]);
        $m = App\Movies::find($id);
        $w->persons()->attach([
            App\Person::name('Roel Reiné')->first()->id => ['role_id' => App\Role::name('director')->first()->id],
            App\Person::name('Alex van Galen')->first()->id => ['role_id' => App\Role::name('writer')->first()->id],
            App\Person::name('Jonathan Banks')->first()->id => ['role_id' => App\Role::name('actor')->first()->id],
        ])

(может быть, есть более чистые способы определения семян)

Это правильно связывает, например, person "Roel Reiné" как role "директор" на movie «Редбад».

Что остается: как получить список людей + роли для мов ie?

Статус на данный момент таков, что я могу получить людей ( без их роли):

tinker:

>>> App\Movie::where('title','Redbad')->with('persons')->get()
=> 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,
               },
             },
    ...

Это дает лиц, участвующих в Redbad mov ie. И в объекте pivot я вижу идентификатор роли.
Это позволяет мне выполнять запросы вроде $movie->persons()->where('role_id',4)->get(), что дает мне все actors для указанного c mov ie или `

Но я бы предпочел загружать роль так же, как человек, чтобы я мог легко составить список фильмов с людьми и их ролью. Например,

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

1 Ответ

1 голос
/ 12 марта 2020

Таблицы, необходимые для определения этого отношения:

users
    id - integer
    name - string
    ...

roles
    id - integer
    name - string
    user_id - integer
    movie_id - integer

movies
    id - integer
    title - string

Реализация

Давайте определим метод фильмов на нашей модели пользователя

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * The roles that belong to the user.
     */
    public function movies()
    {
        return $this->belongsToMany('App\Movie', 'roles', 'user_id', 'movie_id')->withPivot('name');
    }
}

Определение обратного Отношение

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Movie extends Model
{
    /**
     * The users that belong to the role.
     */
    public function users()
    {
        return $this->belongsToMany('App\User', 'roles', 'movie_id', 'user_id')->withPivot('name');
    }
}

Как только отношение определено, вы можете получить доступ к фильмам пользователя, используя свойство movies Dynami c:

$user = App\User::find(1);

foreach ($user->movies as $movie) {
    // You may access the intermediate table using the pivot attribute on the models:
    echo $movie->pivot->name; // retrieve the role name for user #1 in $movie
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...