获取Laravel模型按多对多关系进行过滤

时间:2018-10-14 12:12:39

标签: php laravel laravel-5.7

我有这个电影数据库模式(仅与问题相关的数据):

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();
    }
}

到目前为止一切都很好。

角色之一是“导演”。

现在,我想添加一个“电影”表,该表具有一个外键,该外键具有导演的ID(具有“导演”角色的人)。

films
id
title
director_person_id

在FilmsController的create方法中,我试图将包含导演的列表发送到视图(以显示用于选择一个的选择输入)。

哪种方法是正确的?

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

        $directorsToChoose = Person::  ???

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

我看到了this related question,但在这种情况下我不知道如何应用。

谢谢。

1 个答案:

答案 0 :(得分:1)

将数据透视表键用作另一个表上的外键不是一个好方法。在这种情况下,您可以将主键添加到表中,然后将该键用作外键。

person_roles
id(主键)
role_id
person_id

电影
id
person_role_id(外键)

由于这不是数据透视表,因此也请创建一个Eloquent模型。

PersonRole

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);
    }
}

然后将这些表格ID发送到“电影制作表单”进行选择。

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>