I was used relationships in my model and it's working fine but the sort of output array is wrong.I want to move created_at and updated_at in the end of the array
The output is:
{
"id": 1,
"title": "Test home",
"created_at": "2022-01-01T15:27:31.000000Z", <---------
"updated_at": "2022-01-01T15:27:31.000000Z", <---------
"doors": [
{
"id": 1,
"home_id": 1,
"button_count": 2,
"created_at": null,
"updated_at": null
}
]
}
But it's should be:
{
"id": 1,
"title": "Test home",
"doors": [
{
"id": 1,
"home_id": 1,
"button_count": 2,
"created_at": null,
"updated_at": null
}
],
"created_at": "2022-01-01T15:27:31.000000Z", <---------
"updated_at": "2022-01-01T15:27:31.000000Z" <---------
}
And it's my model class:
class Home extends Model
{
use HasFactory;
protected $table = "homes";
protected $hidden = ["device_id"];
protected $with = ["doors"];
public function device(){
return $this->hasOne(Device::class,"id","device_id");
}
}
CodePudding user response:
The cleanest approach if you are building an API (not sure if your scenario) is by using Resources where you can format the response as you wish. This is also helpful for being sure that Models will be returned with the same structure in all endpoints.
Assuming you want to fetch all homes with their devices, you can create a DeviceResource for returning specific device properties
PHP artisan make:resource DeviceResource
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class DeviceResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
return [
'id' => $this->id,
'home_id' => $this->home_id,
'button_count' => $this->button_count,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
}
}
Then create a HomeResource which will includes DeviceResource
PHP artisan make:resource HomeResource
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class HomeResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
'devices' => DeviceResource::collection($this->whenLoaded('devices')),
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
}
}
Then you just return the HomeResource collection in your controller
$homes = Home::with('devices')->get();
$response = HomeResource::collection($homes);
return $response;
Or in case you want to return only 1 Home...
$home = Home::with('devices')->findOrFail($home_id);
$response = new HomeResource($home);
return $response;
Be aware that if you don't load devices relationships, the HomeResource won't return the devices property.
CodePudding user response:
You can use resouces to map data and organize response like you want
