如何使用 Eloquent ::with 方法获取嵌套关系数据库特定列?
How can I get a nested relationship database specific columns with Eloquent ::with method?
我有以下 3 个表格:
posts<--(hasMany)--users--(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_info 嵌套数据,如下所示:
Post::with('user.userInfo')
其中 returns 是这样的:
{
"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
Eloquent 函数实现此目的?
我已经尝试过 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_picture
和user.userInfo:user.user_info.name,user.user_info.profile_picture
会抛出同样的错误
您可以使用 API 资源
https://laravel.com/docs/7.x/eloquent-resources#introduction
API Resource acts as a transformation layer that sits between your
Eloquent models and the JSON responses that are actually returned to
your application's users.
您可以为 post 创建一个 API 资源,并在响应中 returning post 的任何地方使用它。
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,
]
]
];
}
}
然后在任何你想要的地方return一个post作为回应。
控制器
// $post is a Post Model Instance.
return new PostResource($post);
万一你有 collection
// $posts is a collection of Post Model instances.
return PostResource::collection($posts);
PostResource 将应用于您 collection 中的每个模型实例,然后 return 作为您的 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,
]
];
我有以下 3 个表格:
posts<--(hasMany)--users--(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_info 嵌套数据,如下所示:
Post::with('user.userInfo')
其中 returns 是这样的:
{
"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
Eloquent 函数实现此目的?
我已经尝试过 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_picture
和user.userInfo:user.user_info.name,user.user_info.profile_picture
您可以使用 API 资源 https://laravel.com/docs/7.x/eloquent-resources#introduction
API Resource acts as a transformation layer that sits between your Eloquent models and the JSON responses that are actually returned to your application's users.
您可以为 post 创建一个 API 资源,并在响应中 returning post 的任何地方使用它。
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,
]
]
];
}
}
然后在任何你想要的地方return一个post作为回应。
控制器
// $post is a Post Model Instance.
return new PostResource($post);
万一你有 collection
// $posts is a collection of Post Model instances.
return PostResource::collection($posts);
PostResource 将应用于您 collection 中的每个模型实例,然后 return 作为您的 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,
]
];