【问题标题】:Laravel 5 Eloquent appending relationships to JSON on multiple levelsLaravel 5 Eloquent 在多个级别上将关系附加到 JSON
【发布时间】:2015-06-16 01:47:40
【问题描述】:

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

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
}

【问题讨论】:

    标签: php rest eloquent laravel-5


    【解决方案1】:

    您可以使用 $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”。

    【讨论】:

    • 如果 Roles 是一个关系,它应该是 $this->roles()->get()
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      其他代码本身不需要更改,但总共会进行更多查询。您可以在需要的地方进行显式的 Eager 或惰性 Eager 加载。

      【讨论】:

        【解决方案4】:

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

        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);
        

        然后它将返回如下所示的数组

        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 ) ) )
        

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

        【讨论】:

          猜你喜欢
          • 2021-10-02
          • 2015-04-16
          • 2016-11-19
          • 2021-05-09
          • 2021-01-14
          • 2018-12-14
          • 2018-10-08
          • 2016-03-16
          • 2021-06-30
          相关资源
          最近更新 更多