Laravel 5 Eloquent在多个级别上向JSON添加关系

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Laravel 5 Eloquent在多个级别上向JSON添加关系相关的知识,希望对你有一定的参考价值。

因此,在以下模型中包含关系非常容易:

class User extends Model {
     protected $with=['roles']
}

class Role extends Model {
     protected $with=['permissions']
}

当有对用户资源的get请求时,它将自动包含关联的角色。

但是在此设置中,随用户资源返回的角色资源还包括它自己包含的关系,例如:

{user:{id:1, roles:[{id:1, permissions:[{id:1..

这会生成巨大的对象,主要包括不必要的相关子模型。

我可以通过设置属性来替换默认关系包括解决方法,但我正在处理的API有30多个资源,并且该路径不是理想的因为它需要我在模型上编写大量重复的代码。

有没有办法轻松管理附加关系的深度?

我想象的是:

class Role extends Model {
     protected $with=['permissions'];
     protected $includeWith=[]; // role wont have the permissions appended when included
}
答案

如果有人仍然对此解决方案感兴趣:Laravel 5.5引入了Api Resources,这是组织api响应的好方法。只是不要在模型上包含任何关系并将它们附加到资源上。

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\Resource;

class UserResource extends Resource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email,
            'created_at' => $this->created_at,
            'updated_at' => $this->updated_at,
            'roles'=> $this->roles

        ];
    }
}
另一答案

您可以使用$ appends滚动自己的属性,而不是内置的'$ with'数组:

class User extends Model
{
    protected $appends = ['roles_list'];

    // ...
    // other stuff here, like relationship definitions
    // ...

    public function getRolesListAttribute()
    {
        return $this->roles;
        //OR build 'roles_list' manually, returning whatever you like.
    }
}

唯一的缺点是你必须在接收端注意'roles_list'而不是'roles'。

另一答案

如果对象大小和内存使用率成为一个问题,那么在某些情况下你只需要关闭它。

其他代码本身不需要更改,但总共会进行更多查询。如果需要,您可以进行明确的急切或懒惰的急切加载。

以上是关于Laravel 5 Eloquent在多个级别上向JSON添加关系的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5.4:使用eloquent和fillable字段更新多个表的多个模型

Laravel 5 变量构造查询字符串 Eloquent

Laravel 5.3 Eloquent 交易和外键限制

Laravel Eloquent - 来自相关数据的多个记录的列值的总和

如何使用 eloquent 在 laravel 中编写多个连接

Laravel 5.2 Eloquent ORM 从 3 个表中获取数据