Laravel - 如何链接 Eloquent 关系 - 预加载

Laravel - How to chain Eloquent relationship - Eager Loading

我正在使用来自 hereEloquent 关系的 Laravel 5.4Laravel Roles

我正在尝试检索公司的用户及其角色。

User::find(1)->roles 获取 id =1

的用户角色

Company::find(1)->users 获取属于公司 id =1(没有用户角色)的所有用户。

Company::find(1)->users->roles returns 一个错误 Property [roles] does not exist on this collection instance.

问题

  1. 是否可以做我想做的事?
  2. 如果可以,我应该怎么做?

User.php

class User extends Authenticatable
{
    use HasRoleAndPermission;

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

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

HasRoleAndPermission.php

trait HasRoleAndPermission
{
    public function roles()
    {
        return $this->belongsToMany(config('roles.models.role'));
    }
}

Company.php

class Company extends Model
{
    public function users() {
        return $this->hasMany('App\User');
    }
}

1家公司有很多用户。

1 个用户有多个角色。

您正在尝试获取一组用户的角色(属性 仅存在于一个用户)因此,该集合不存在 属性。

如果想获取公司所有用户的所有角色,可以试试上面的代码:

$roles = [];
Company::find(1)->users->foreach(function($user) {
    $roles = array_merge($roles, $user->roles);
});

------------编辑--------

如@Ohgodwhy 所建议的那样,为了预先加载用户的角色,您必须使用 with,但我会稍微重构一下:

$users = User::with('roles')->where('company_id', $companyId)->get();

现在您拥有大量急切加载其角色的用户。你仍然不能直接访问$users->roles,你必须先获取一个user,然后才能获取它的roles

$company = Company::with('users.roles')->find(1);

将加载所有用户,以及每个用户的所有角色。

更新

根据您的评论,您不需要公司数据。只是用户和角色使用预先加载和关系存在。

$users = User::with('roles')
->whereHas('company' => function($query){
    $query->where('name', '=', 'company'); //If you don't have the company ID
})->get();

不存在关系

$users = User::where('company_id', 1)->with('roles')->get();