I have this model:
AppControllersImageController.php
.....
$image = new Image;
$image->id = "pre_" . (string) Str::ulid()->toBase58();
$image->filename = $filename
$image->post_id= $post_id;
$image->save();
return $image->load("post:id,status,subject,body");
it is working fine, it returns the following:
{
"id": "pre_1BzVrTK8dviqA9FGxSoSnU",
"type": "document",
"filename": "v1BzVc3jJPp64e7bQo1drmL.jpeg",
"post_id": "post_1BzVc3jJPp64e7bQo1drmL",
"post": {
"id": "post_1BzVc3jJPp64e7bQo1drmL",
"status": "active"
....
}
....
}
AppModelsImage.php
class Image extends Model
{
use HasFactory;
public $incrementing = false;
public function post()
{
return $this->belongsTo(Post::class);
}
}
The issue here is that I don’t want it returns the "post_id" field, I would like to get the following:
{
"id": "pre_1BzVrTK8dviqA9FGxSoSnU",
"type": "document",
"filename": "v1BzVc3jJPp64e7bQo1drmL.jpeg",
"post": {
"id": "post_1BzVc3jJPp64e7bQo1drmL",
"status": "active"
....
}
....
}
I tried this:
return $image->select(["id", "type", "filename"])->load("post:id,status,subject,body");
and it returns an error:
"message": "Call to undefined method
IlluminateDatabaseEloquentBuilder::load()",
What can I do?
2
Answers
Try use and eloquent API Resources to make and format and load fields from to relationships, check documentation
And call this resource in your controller
The code you’ve tried
has actually multiple issues and is mixing a few things up.
The first issue is that you are already have an image model and try to select only a few columns, which will actually create a new query for another image. What you can do instead is select only the required columns before loading the image, e.g.:
The problem with this solution leads us to the second problem though:
When you don’t select the
post_id
, Laravel won’t be able to load the relationship due to the missing foreign key.If the query statement was correct, it would actually execute two queries:
But since you’ve not included the
post_id
in the first query, it is not available as parameter for the second query and it fails to load the relationship data.Possible solution #1: API resources
Use an API resource to transform the image before returning it. This is best practice as it allows you to decouple the internal data structure from the public data structure. It will also prevent unwanted API changes when the internal data structure changes (new column is added, a column is renamed, a column is deleted, …).
In your case, the solution could be as simple as:
Possible solution #2: Hide fields
You can define hidden fields in your models using the
$hidden
property. These fields will not be serialized to JSON:Alternatively, you can use
$visible
to define a whitelist instead of a blacklist. Only the properties in the$visible
array will be serialized:This solution will obviously affect the entire application and may therefore be not ideal.
Possible solution #3: Temporarily set hidden/visible properties
Instead of permanently setting
$hidden
or$visible
, you can also temporarily set them in your controller: