Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel Eloquent get all in single key value pair

I have two tables posts and post_metas with the schema as below:

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         |

using a simple one to many relationship, i get this output

[
  {
    "id": 1,
    "title": "Dibbert LLC",
    "content": null,
    "post_metas": [
      {
        "key": "code",
        "value": "YSRSLBZ7"
      },
      {
        "key": "agent_id",
        "value": "32"
      }
    ]
  }
]

I am wondering if it is possible to have the post metas as an object not an array, like this instead:

[
  {
    "id": 1,
    "title": "Dibbert LLC",
    "content": null,
    "post_metas": {
        "code": "YSRSLBZ7",
        "agent_id": "32"
      }
  }
]
like image 903
Salal Aslam Avatar asked Dec 18 '22 20:12

Salal Aslam


2 Answers

You can't change how Eloquent returns relationship collections, nor should you want to, but you can certainly manipulate the collection in your response:

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

Read up on all the available collection methods.

like image 127
Devon Avatar answered Dec 20 '22 17:12

Devon


Laravel by default return an instance of the Collection class. This is also applied when querying relationship elements.

Now, if you want to customize the fields to be returned (hide, transform or add something, for example), you could use API Resources. This will let you easily transform your responses.

Check this other answer to help you with API Resources.


Update

To implement API Resources to your needs we'll need to:

  1. Define the PostResource and PostMetaResource classes.
  2. Customize them
  3. Use them in the controller to return the desired data to the view/API

Defining API Resources classes

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

Customization

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')),
        ];
    }
}

Applying them

use App\Http\Resources\PostResource;

//

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

    return PostResource::collection($posts);
}
like image 36
Kenny Horna Avatar answered Dec 20 '22 16:12

Kenny Horna