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

Laravel 5 Eloquent appending relationships to JSON on multiple levels

因此很容易在模型中包含关系,例如:

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

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

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

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

{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
}

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

其他代码本身不用改,但总的来说查询会多一些。在需要的地方,您可以进行显式预加载或惰性预加载。

您可以使用 $appends:

滚动您自己的属性,而不是 built-in '$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.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

        ];
    }
}

如果您已经声明了关系并且想要附加该关系数据,那么您可以像下面的示例那样做

class User extends Model
{
    /* your other code */

    /**
      * The accessors to append to the model's array form.
      *
      * @var array
      */
    protected $appends = [
        'company_list',
    ];

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

    /**
     * Get the Companies List with User Id.
     *
     * @return array
     */
     public function getCompanyListAttribute()
     {
        return $this->company()->get();
     }

     /**
      * Get the company for the user.
      * 
      * one-to-many relationship
      */
     public function Company()
     {
         return $this->hasMany(CompanyList::class, 'company_owner_id');
     }
}

现在,它将在用户详细信息数组中附加公司详细信息

例如,我使用这样的用户 ID 获取用户详细信息

 echo User::find(2);

然后它将 returns 数组如下

Array ( [id] => 2 [name] => Merritt Roob [email] => kerluke.mariano@example.net [email_verified_at] => 2021-12-07T08:34:43.000000Z [contact] => [profile_photo_path] => [created_at] => 2021-12-07T08:34:43.000000Z [updated_at] => 2021-12-07T08:34:43.000000Z [company_list] => Array ( [0] => Array ( [id] => 1 [company_name] => Prof. Dorcas Strosin II [company_email] => paxton91@example.com [company_contact] => 1-986-702-4140 [company_owner_id] => 2 [created_at] => 2021-12-07T08:34:43.000000Z [updated_at] => 2021-12-07T08:34:43.000000Z ) ) )

我希望上面的例子对其他人有帮助谢谢