Laravel hasManyThrough与ManyToMany pivot

时间:2018-01-10 14:51:16

标签: laravel model eloquent relationship laravel-eloquent

我正在制作一个游戏,我有用户有设施,为此我使用ManyToMany

user_facilities
    -user_id
    -facility_id

但是每个关系必须具有设施级别,因此我添加了facility_levels表,并且每个级别必须连接到ManyToMany关系。所以user_facilities现在看起来像这样

user_facilities
        -user_id
        -facility_id
        -level_id

level_id 是用户拥有的设施与其所在级别之间的连接。

我的问题是如何在模型中连接它?

用户模型现在有了这个

public function facilities()
{
    return $this->belongsToMany('App\Facility', 'user_facilities');
}

和设施

public function users()
{
    return $this->belongsToMany('App\User', 'user_facilities');
}

那么如何获得用户拥有的设施级别? 在刀片中我希望有一种方法可以使用像

这样的东西
{{ $user->facility->level->property }}

1 个答案:

答案 0 :(得分:2)

leveluser_facilities表中不属于facility

的一部分

因此,您应该可以从用户设施的多对多关系访问level_id

您可以做的一件事是访问直接表(也称为数据透视表)。

首先,编辑您的关系以包含额外属性。

public function facilities()
{
    return $this->belongsToMany('App\Facility', 'user_facilities')
                ->withPivot('level_id');
}

public function users()
{   // if you omit this EDIT/UPDATE, you cannot do this:
    // $facility->users()->first()->pivot->level_id;
    return $this->belongsToMany('App\User', 'user_facilities')
                ->withPivot('level_id');
}

请注意,当访问多对多关系时,Laravel会立即为结果分配一个pivot属性,其中包含有关两个模型的数据透视表的详细信息

现在尝试访问额外的列:

$facility = $user->facilities->first();
$level_id = $facility->pivot->level_id;
// now you can use $level_id for finding the level.
$level = Level::find($level_id);

现在,既然你可以这样做,你也可以为用户设施多对多关系创建一个模型,拥有level_id

的属性

让我们创建一个名为UserFacility的新模型,它将扩展Pivot

这将是您的用户和设施的多对多关系的Pivot模型。

use Illuminate\Database\Eloquent\Relations\Pivot;

class UserFacility extends Pivot
{
}

然后按如下方式更新您的usersfacilities关系。

public function facilities()
{
    return $this->belongsToMany('App\Facility', 'user_facilities')
                ->using('App\UserFacility');
}

public function users()
{
    return $this->belongsToMany('App\User', 'user_facilities')
                ->using('App\UserFacility');
}

请注意using方法。

$userfac = $users->facilities->pivot; // <-- pivot will now be an instance of App\UserFacility
echo $userfac->level_id;

最后,

如果您不想要pivot属性名称,可以使用as方法更改它,在belongsToMany方法之后将其链接,如下所示:

public function users()
{
    return $this->belongsToMany('App\User', 'user_facilities')
                ->as('UFac')
                ->using('App\UserFacility');
}


$userfac = $users->facilities->UFac; // <-- you can now access the pivot table using the property `UFac`
echo $userfac->level_id;

您的数据透视表也可能与level有关系,因为它有level_id。不用担心,只需在UserFacility模型中添加此功能即可。

public function level()
{
    return $this->belongsTo('App\Level');
}

现在你可以做到这一点!

$user->facilities->first()->UFac->level; // <-- this will be an instance of App\Level

来源:https://laravel.com/docs/5.5/eloquent-relationships#many-to-many