Reputation: 6612
Suppose we have a Product
model like this :
class Product extends Model
{
protected $appends = ['picture'];
public function getPictureAttribute()
{
$picture = NULL;
if (!$this->images->isEmpty()) {
$picture = $this->images->where('selected', TRUE)->first()->path;
}
return $picture;
}
public function images()
{
return $this->morphMany(Image::class, 'imageable');
}
}
In the other hand there is an Image
model like this :
class Image extends Model
{
protected $fillable = ['title', 'path', 'imageable_id', 'imageable_type', 'selected'];
public function imageable()
{
return $this->morphTo();
}
}
As you can see each product can have many images. one of those images can be selected as default and now I want when fetch a Product
,that be include a picture
field that holds path
of that selected image. for this I appended a picture
attribute to Product
model as an accessor.
But each time I call a specific product for example in show
controller method like this :
public function show(Product $product)
{
return $product;
}
Result is like this (a images
property is included automatically ) :
{
"product_id": 1,
"code": null,
"created_at": "2017-12-11 12:21:49",
"updated_at": "2018-01-23 09:38:38",
"deleted_at": null,
"picture": "path 2",
"images": [
{
"id": 9,
"title": "salam",
"path": "path 1",
"imageable_id": 1,
"imageable_type": "Modules\\Product\\Entities\\Product",
"selected": 0,
"created_at": "2018-01-23 09:38:38",
"updated_at": "2018-01-23 09:38:38"
},
{
"id": 10,
"title": "in the name of god",
"path": "path 2",
"imageable_id": 1,
"imageable_type": "Modules\\Product\\Entities\\Product",
"selected": 1,
"created_at": "2018-01-23 09:38:38",
"updated_at": "2018-01-23 09:38:38"
}
],
"title": "Updataed Title"
}
I don't know what is problem and how can I solve that.
Upvotes: 1
Views: 131
Reputation: 6720
The cause of the images relationship being shown is because it's part of the Model attributes once you retrieve it within the picture accessor.
One of the better practices in my opinion is using transformers which control the data shown in the api response. League fractal offers such functionality. What a transformer does is filter the output; much like an outward middleware. Transformers also offer the ability of includes, allowing you to only show specific data when specifically requested.
Upvotes: 1