如何使用Eloquent :: with方法获取嵌套关系数据库特定的列?

时间:2020-08-01 20:19:15

标签: php mysql laravel eloquent lumen

我有以下3张桌子:

帖子 <-(hasMany)-用户-(hasOne)-> user_info

-------------------------------------------------
                     Post
-------------------------------------------------
id | user_id | content | created_at | updated_at
----------------------------------------------------------------------------------------
                                           users
----------------------------------------------------------------------------------------
id | user_info_id | email| username | password | access_token | created_at | updated_at
------------------------------------------------------------------------------------------------------------
                                                      user_info
------------------------------------------------------------------------------------------------------------
id | user_id | name | web | birthday | gender | bio_description | profile_picture | created_at | updated_at

关系建立如下:

User.php

...
    public function userInfo() {
        return $this->hasOne('App\UserInfo');
    }
...
    public function posts() {
        return $this->hasMany('App\Post');
    }
...

UserInfo.php

...
    public function user() {
        return $this->belongsTo('App\User');
    }
...

Post.php

...
    public function user() {
        return $this->belongsTo('App\User');
    }
...

我得到了所有带有user和user_info嵌套数据的帖子,像这样:

Post::with('user.userInfo')

返回如下内容:

{
    "data": [
        {
            "id": 1,
            "created_at": "2020-08-01 06:10:00",
            "updated_at": "2020-08-01 06:10:00",
            "user_id": 1,
            "content": "My first post!",
            "user": {
                "id": 1,
                "user_info_id": 1,
                "email": "myemail@gmail.com",
                "username": "derek",
                "access_token": "secret",
                "created_at": "2020-08-01 04:15:09",
                "updated_at": "2020-08-01 04:15:09",
                "user_info": {
                    "id": 1,
                    "user_id": 1,
                    "name": "Derek Baker",
                    "web": "https://github.com/derek90",
                    "birthday": "1990-11-27",
                    "gender": "M",
                    "bio_description": "Software Developer",
                    "profile_picture": null
                }
            }
        },
        {
            "id": 2,
            "created_at": "2020-08-01 06:09:54",
            "updated_at": "2020-08-01 06:09:54",
            "user_id": 1,
            "content": "My second post!",
            "user": {
                "id": 1,
                "user_info_id": 1,
                "email": "myemail@gmail.com",
                "username": "derek",
                "remember_token": null,
                "access_token": "secret",
                "created_at": "2020-08-01 04:15:09",
                "updated_at": "2020-08-01 04:15:09",
                "user_info": {
                    "id": 1,
                    "user_id": 1,
                    "name": "Derek Baker",
                    "web": "https://github.com/derek90",
                    "birthday": "1990-11-27",
                    "gender": "M",
                    "bio_description": "Software Developer",
                    "profile_picture": null
                }
            }
        }
    ]
}

我想要的是仅获取每个实体的几列,如下所示:

{
    "data": [
        {
            "id": 1,
            "created_at": "2020-08-01 06:10:00",
            "updated_at": "2020-08-01 06:10:00",
            "content": "My first post!",
            "user": {
                "id": 1,
                "username": "derek",
                "user_info": {
                    "name": "Derek Baker",
                    "profile_picture": null
                }
            }
        },
        {
            "id": 2,
            "created_at": "2020-08-01 06:09:54",
            "updated_at": "2020-08-01 06:09:54",
            "content": "My second post!",
            "user": {
                "id": 1,
                "username": "derek",
                "user_info": {
                    "name": "Derek Baker",
                    "profile_picture": null
                }
            }
        }
    ]
}

是否有一种方法可以使用Post::with雄辩的功能?

我已经尝试过Post::with('user:id,username', 'user.userInfo'),它对于用户列很有效,但是userInfo带来了所有功能。

我尝试过的其他事情:

Post::with('user:id,username', 'user.userInfo:name,profile_picture')"user_info": null带入json字段

Post::with('user:id,username', 'user.userInfo:userInfo.name,userInfo.profile_picture')显示错误Unknown column 'userInfo.name' in 'field list'

使用user.userInfo:user.userInfo.name,user.userInfo.profile_pictureuser.userInfo:user.user_info.name,user.user_info.profile_picture抛出相同的错误

1 个答案:

答案 0 :(得分:1)

您可以使用API​​资源 https://laravel.com/docs/7.x/eloquent-resources#introduction

API资源充当位于您之间的转换层 口才的模型和实际返回的JSON响应 您应用程序的用户。

您可以为帖子创建API资源,并在响应中返回帖子的任何地方使用它。

Api资源为您提供了更多控制权,您可以操纵所需的任何字段,使用几个字段的组合发送一些额外的字段,更改响应中所需的字段的名称(xyz => $this->name

PostResource

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class PostResource extends JsonResource
{
    public function toArray($request)
    {
        //You can access model properties directly using $this

        return [
            "id" => $this->id,
            "created_at" => $this->created_at,
            "updated_at" => $this->updated_at,
            "content" => $this->content,
            "user" => [
                "id" => $this->user->id,
                "username" => $this->user->username,
                "user_info" => [
                    "name" => $this->user->userInfo->name,
                    "profile_picture" => $this->user->userInfo->profile_picture,
                ]
            ]
        ];
    }
}

然后返回您希望返回帖子的任何地方。

控制器

// $post is a Post Model Instance.

return new PostResource($post); 

如果您有收藏夹

// $posts is a collection of Post Model instances.

return PostResource::collection($posts);

PostResource将应用于集合中的每个模型实例,然后作为JSON响应返回给您。

[注意]

您可以为用户和任何模型创建类似的资源。可以更轻松地自定义响应。

此外,在上述示例中。除了在用户内部使用user_info之外,您还可以仅将user_info属性添加到用户中。

        return [
            "id" => $this->id,
            "created_at" => $this->created_at,
            "updated_at" => $this->updated_at,
            "content" => $this->content,
            "user" => [
                "id" => $this->user->id,
                "username" => $this->user->username,
                "name" => $this->user->userInfo->name,
                "profile_picture" => $this->user->userInfo->profile_picture,
            ]
        ];