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

时间:2018-11-01 01:04:14

标签: laravel laravel-5 eloquent laravel-5.7

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

我有两个模型,App\Models\UserApp\Models\Group和一个枢轴模型App\Pivots\GroupUser

我的表具有以下结构

用户

  • id

  • id

group_user

  • id
  • user_id
  • group_id

我目前将关系定义为

在app / Models / User.php中

public function groups()
{
    return $this->belongsToMany(Group::class)->using(GroupUser::class);
}

在app / Models / Group.php中

public function users()
{
    return $this->belongsToMany(User::class)->using(GroupUser::class);
}

在app / Pivots / GroupUser.php中

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

public function group()
{
    return $this->belongsTo(Group::class);
}

我正在尝试在我的User类中定义一种关系,以访问同一组中的所有其他相关用户。称为friends。到目前为止,我已经尝试过:

app / Models / User.php

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

但是最终它只返回了一个我调用了该关系的用户的集合。 (与运行collect($this);

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

app / Models / 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;
}

是否可以使用hasManyThrough或其他一些雄辩的函数来完成此任务?

谢谢。

2 个答案:

答案 0 :(得分:0)

您是否尝试过Eager Loading。希望有帮助。

答案 1 :(得分:0)

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

app / Models / 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;
}

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