Laravel hasOne 通过数据透视表

Chr*_*ton 7 php relationship laravel eloquent

所以我有2个模型,User & Profile,关系设置如下:

    /**
     * User belongs to many Profile
     *
     * @return \Illuminate\Database\Eloquent\Relations\belongsToMany
     */
    public function profiles()
    {
        return $this->belongsToMany('App\Models\Profile', 'user_profiles');
    }
Run Code Online (Sandbox Code Playgroud)

我有 3 个表、用户、配置文件和 user_profiles(数据透视表)

我的用户表中有一个名为的列,active_profile其中填充了配置文件 ID。

我如何建立关系,以便我可以调用以下内容:

$user->active_profile

以便它将返回active_profile中设置的id的所有配置文件信息?

cba*_*ier 5

在 Laravel 5.8 上,因为我想通过急切加载来使用它,所以我使用了这个包: https: //github.com/staudenmeir/eloquent-has-many-deep

这是我的场景
一个用户可以在许多照片上被标记,并且一张照片可以有许多用户被标记。我想建立一种关系来获取用户被标记的最新照片。

我认为我的场景也可以应用于任何多对多关系

我做了枢轴模型UserPhoto

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Relations\Pivot;

class UserPhoto extends Pivot
{

    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function photo()
    {
        return $this->belongsTo(Photo::class);
    }

}
Run Code Online (Sandbox Code Playgroud)

然后在我的User模型上使用staudenmeir的包:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Staudenmeir\EloquentHasManyDeep\HasRelationships;

class User extends Model
{
    use HasRelationships;

    public function photos()
    {
        return $this->belongsToMany(Photo::class);
    }

    public function latestPhoto()
    {
        return $this->hasOneDeep(Photo::class, [UserPhoto::class])
            ->latest();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我可以轻松地做这样的事情:

User::with('latestPhoto')->get()$user->latestPhoto


编辑:在另一个问题中,有人在没有使用包的情况下问了同样的问题。我还提供了一个会产生相同结果的答案。

但深入挖掘后,从这两个答案中,您可以避免 n+1 查询,您仍然会水合来自您请求的用户的所有照片。我认为不可能避免其中一种方法。不过,缓存可能是一个答案。


Amr*_*Aly 0

您可以将方法添加到User模型中,如下所示:

public function active_profile ()
{
   return $this->profiles()
          ->find($this->active_profile);
}
Run Code Online (Sandbox Code Playgroud)

然后你可以调用该方法 $user->active_profile();