在数据透视表上使用 hasManyThrough 检索相关模型 - Laravel 5.7

Sam*_*lor 6 laravel eloquent laravel-5 laravel-5.7

我正在尝试从数据透视表中检索相同类型的相关模型。

我有 2 个模型App\Models\UserApp\Models\Group一个枢轴模型App\Pivots\GroupUser

我的表具有以下结构

用户

  • ID

团体

  • ID

组用户

  • ID
  • 用户身份
  • 组ID

我目前将关系定义为

在应用程序/模型/User.php

public function groups()
{
    return $this->belongsToMany(Group::class)->using(GroupUser::class);
}
Run Code Online (Sandbox Code Playgroud)

在应用程序/模型/Group.php

public function users()
{
    return $this->belongsToMany(User::class)->using(GroupUser::class);
}
Run Code Online (Sandbox Code Playgroud)

在应用程序/Pivots/GroupUser.php

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

public function group()
{
    return $this->belongsTo(Group::class);
}
Run Code Online (Sandbox Code Playgroud)

我试图在我的User班级中定义一个关系,以访问同一组中相关的所有其他用户。呼唤着它friends。到目前为止我已经尝试过这个:

应用程序/模型/User.php

public function friends()
{
    return $this->hasManyThrough(
        User::class,
        GroupUser::class,
        'user_id',
        'id'
    );
}
Run Code Online (Sandbox Code Playgroud)

但它最终只是返回一个集合,其中仅包含我调用关系的用户。(与运行相同collect($this);

我有一个可行的解决方案,但并不理想。

应用程序/模型/User.php

public function friends()
{
    $friends = collect();
    foreach($this->groups as $group) {
        foreach($group->users as $user) {
            if($friends->where('id', $user->id)->count() === 0) {
                $friends->push($user);
            }
        }
    }

    return $friends;
}
Run Code Online (Sandbox Code Playgroud)

有没有办法可以使用hasManyThrough其他 Eloquent 函数来完成此操作?

谢谢。

new*_*e02 3

您不能使用此方法来执行此操作hasManyThrough,因为表上没有外键users将其与id表的相关联group_user。您可以尝试使用现有关系从用户到他们的组再到他们的朋友belongsToMany

应用程序/模型/User.php:

// create a custom attribute accessor
public function getFriendsAttribute()
{
    $friends = $this->groups()                                          // query to groups
                    ->with(['users' => function($query) {               // eager-load users from groups
                        $query->where('users.id', '!=', $this->id);     // filter out current user, specify users.id to prevent ambiguity
                    }])->get()
                    ->pluck('users')->flatten();                        // massage the collection to get just the users

    return $friends;
}
Run Code Online (Sandbox Code Playgroud)

然后,当您调用时,$user->friends您将获得与当前用户属于同一组的用户集合。