Laravel Eloquent获取所有单键值对的方法

6

我有两个表postspost_metas,其模式如下:

POSTS
+------------+------------------+
| Field      | Type             |
+------------+------------------+
| id         | int(10) unsigned |
| title      | varchar(255)     |
| content    | longtext         |


POST_METAS
+------------+------------------+
| Field      | Type             |
+------------+------------------+
| id         | int(10) unsigned |
| post_id    | int(10) unsigned |
| key        | varchar(255)     |
| value      | longtext         |

使用简单的一对多关系,我得到了以下输出。
[
  {
    "id": 1,
    "title": "Dibbert LLC",
    "content": null,
    "post_metas": [
      {
        "key": "code",
        "value": "YSRSLBZ7"
      },
      {
        "key": "agent_id",
        "value": "32"
      }
    ]
  }
]

我想知道是否可能将文章元数据作为对象而不是数组,如下所示:
[
  {
    "id": 1,
    "title": "Dibbert LLC",
    "content": null,
    "post_metas": {
        "code": "YSRSLBZ7",
        "agent_id": "32"
      }
  }
]

你是如何查询 post 并获取 post_meta 的呢?Laravel 确实会返回一个对象集合,看起来就像你想要的输出。 - Kenny Horna
2个回答

14

您不能更改Eloquent返回的关系集合的方式,也不应该这样做,但您可以在响应中对集合进行操作:

$model->post_metas->pluck('value', 'key');

阅读所有可用的集合方法


1
默认情况下,Laravel 返回 Collection 类的实例。当查询关联元素时也是如此。
现在,如果您想自定义要返回的字段(例如隐藏、转换或添加一些内容),可以使用 API Resources。这将让您轻松地转换响应。
查看 这个答案 以帮助您理解 API 资源。

更新

为了满足您的需求,我们需要实现API资源,步骤如下:

  1. 定义PostResource和PostMetaResource类。
  2. 自定义它们。
  3. 在控制器中使用它们将所需数据返回到视图/API。

定义API资源类

php artisan make:resource PostMetaResource
php artisan make:resource PostResource

自定义

App/Http/Resources/PostMetaResource.php

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\Resource;

class PostMetaResource extends Resource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'key' => $this->key,
            'value' => $this->value,
        ];
    }
}

App/Http/Resources/PostResource.php

class PostResource extends Resource
{

    use PostMetaResource;

    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'title' => $this->title,
            // the rest of your fields..

            // here is where we load the relationship resource:
            'post_metas' => PostMetaResource::collection($this->whenLoaded('post_metas')),
        ];
    }
}

应用它们

use App\Http\Resources\PostResource;

//

public function index(Request $request)
{
    $posts = Post::with('post_metas')->get();

    return PostResource::collection($posts);
}

这是目前我正在做的事情,我更感兴趣的是你提到的最后一部分。 - Salal Aslam
哈哈,我发这个是因为你现在的输出方式看起来有点不对。我更新了我的答案,添加了一个链接,指向我过去关于该主题(API资源)的回答。 - Kenny Horna
我在模型中使用了toArray方法,只返回键和值字段,同时省略了id和post_ids以尽可能简洁地提出问题。 - Salal Aslam
你能否更新你的答案,包括Resource方法,以便给我提供我在问题中提到的输出? - Salal Aslam
@SalalAslam 完成了。我鼓励你阅读有关这个主题的文档。比我的回答更清晰明了。祝你有美好的一天。 - Kenny Horna

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接