获取 Laravel 个按多对多关系过滤的模型

Get Laravel models filtering by many to many relationship

我有这个电影数据库架构(只有与问题相关的数据):

persons (yes, I used "persons" instead of "people"...)
id
name

roles
id
name

roles_persons
person_id
role_id

和对应的模型,定义多对多的关系:

class Person extends Model
{
    protected $table = 'persons';

    public function roles(){
        return $this->belongsToMany('App\Role', 'roles_persons')->withTimestamps();
    }
}

class Role extends Model
{
    public function persons(){
        return $this->belongsToMany('App\Person', 'roles_persons')->withTimestamps();
    }
}

到目前为止一切正常。

其中一个角色是 "director"。

现在我想添加一个"films" table,它有一个外键,id是一个director(一个有"director"角色的人)。

films
id
title
director_person_id

在 FilmsController 的创建方法中,我试图向视图发送一个包含导演的列表(为了显示 select 输入以选择一个)。

哪种方法正确?

class FilmsController extends Controller
{
    public function create()
    {
        $directorRole = Role::find('1');

        $directorsToChoose = Person::  ???

        return view('films.create')->with('directors', $directors);
    }
}

我看到了 this related question 但我不明白如何在这种情况下应用它。

谢谢。

使用 Pivot Table 键作为另一个 table 上的外键不是一个好方法。在这种情况下,您可以将主键添加到 table 并将该键用作外键。

person_roles
id(主键)
role_id
person_id

电影
编号
person_role_id(外键)

因为这不是枢轴 Table,所以也创建一个 Eloquent 模型。

人物角色

class PersonRole extends Model
{
    protected $table = 'persons_roles';

    public function role()
    {
        return $this->belongsTo(Role::class);
    }

    public function person()
    {
        return $this->belongsTo(Person::class);
    }
}

class Person extends Model
{
    protected $table = 'persons';

    public function personRole
    {
        return $this->hasMany(PersonRole::class);
    }
}

角色

class Person extends Model
{
    protected $table = 'roles';

    public function personRole
    {
        return $this->hasMany(PersonRole::class);
    }
}

然后将那些 tables id 发送到电影创建表单到 select。

class FilmsController extends Controller
{
    public function create()
    {
        $directors = PersonRole::whereHas('role', function ($roles) {
            $roles->where('name', 'director');
        })
        ->with('person')
        ->get();

        return view('films.create')->with('directors', $directors);
    }
}

查看

<select>
    @foreach($directors as $director)
        <option value="{{ $director->id }}">{{ $director->person->name }}</option>
    @endforeach
</select>