How to remove pivot keyword from json using laravel?

2.8k Views Asked by At

I am trying to fetch data from games table which has pivot table user_games. Below code if works fine for me

$UserGames = User::with(['games' => function ($query){
    $query->withPivot('highscore','level');
}])->find(request()->user()->id);

I am getting following json response

{
    "data": [
        {
            "id": 2,
            "name": "culpa",
            "type_id": 3,
            "created_at": "2018-10-30 11:23:27",
            "updated_at": "2018-10-30 11:23:27",
            "pivot": {
                "user_id": 2,
                "game_id": 2,
                "highscore": 702,
                "level": 3
            }
        }
    ]
}

But I wanted to remove pivot keyword from above json and pull pivot detail into root as like below my desire response

{
    "data": [
        {
            "id": 2,
            "name": "culpa",
            "type_id": 3,
            "created_at": "2018-10-30 11:23:27",
            "updated_at": "2018-10-30 11:23:27",
            "user_id": 2,
            "highscore": 702,
            "level": 3
        }
    ]
}

Can someone kindly guide me how to fix the issue. I would appreciate. Thank you so much

4

There are 4 best solutions below

0
On

You can override the User model's jsonSerialize method which is called in the toJson method, this is the initial method body:

public function jsonSerialize()
{
    return $this->toArray();
}

And you can do something like this:

public function jsonSerialize()
{
    $attrs = $this->toArray();

    if (isset($attrs['pivot'])) {
        $attrs = array_merge($attrs, $attrs['pivot']);
        unset($attrs['pivot']);
    }

    return $attrs;
}
4
On

You can utilise hidden and appends on the pivot model to re-structure the returned data.

class PivotModel extends model
{
    protected $hidden = ['pivot'];
    protected $appends = ['user_id'];

    public function getUserIdAttribute()
    {
        return $this->pivot->user_id;
    }
}

Reference for hidden

Reference for appends

1
On

You can convert the json into an array than reconvert it to json.

$UserGames = User::with(['games' => function ($query){
    $query->withPivot('highscore','level');
}])->find(request()->user()->id);

$UserGames = json_decode($UserGames, true);

$pivot = $UserGames['data'][0]['pivot'];

unset($UserGames['data'][0]['pivot']);

$UserGames = json_encode(array_merge($UserGames[0], $pivot));
0
On

I highly recommend to use API Resource to modify response layer.

for this question, create an api resource using php artisan make:resource UserGameResource

public function toArray($request)
{
    'id' => $this->id,
    'name' => $this->name,
    'type_id' => $this->type_id,
    'created_at' => $this->created_at,
    'updated_at' => $this->updated_at,
    'user_id' => $this->pivot->user_id,
    'highscore' => $this->pivot->highscore,
    'level' => $this->pivot->level,
}

and finally return your query result using this api resouce:

$UserGames = <your query>
$response = UserGamesResource::collection($UserGames);