Laravel 5 Eloquent 在多个级别上将关系附加到 JSON

Con*_*hol 6 php rest eloquent laravel-5

因此,在模型上包含关系非常容易,例如:

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

class Role extends Model {
     protected $with=['permissions']
}
Run Code Online (Sandbox Code Playgroud)

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

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

{user:{id:1, roles:[{id:1, permissions:[{id:1..
Run Code Online (Sandbox Code Playgroud)

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

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

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

我想像这样:

class Role extends Model {
     protected $with=['permissions'];
     protected $includeWith=[]; // role wont have the permissions appended when included
}
Run Code Online (Sandbox Code Playgroud)

Rob*_*ert 8

您可以使用 $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.
    }
}
Run Code Online (Sandbox Code Playgroud)

唯一的缺点是您必须在接收端注意“roles_list”而不是“roles”。

  • 如果 Roles 是一种关系,则应该是 $this->roles()->get() (2认同)

Con*_*hol 8

如果有人仍然对此解决方案感兴趣: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

        ];
    }
}
Run Code Online (Sandbox Code Playgroud)