Reputation: 3411
On my project, Picture model has some "one to many" relations to create featured images. Those relations:
public function featuredByPosts()
{
return $this->hasMany('App\Post', 'featured_image_id');
}
public function featuredByProduct()
{
return $this->hasMany('App\Products', 'featured_image_id');
}
public function featuredByPages()
{
return $this->hasMany('App\Page', 'featured_image_id');
}
One of the inverse relations is like so:
public function featured_image()
{
return $this->belongsTo('App\Picture', 'featured_image_id');
}
When I get the pictures with those relations, each picture in collection has featured_by_posts, featured_by_products and featured_by_pages keys and related content as values of those keys.
What I want to do is to create a new key named "featured_by" directly in each picture in the collection and move current featured_by_* relations into new key by modifing their keys like so:
From this:
$picture = [
"id" => "1",
"name" => "someName",
"featured_by_posts" => [array of posts],
"featured_by_pages" => [array of pages]
]
To this:
$picture= [
"id" => "1",
"name" => "someName",
"featured_by" => [
"posts" => (values of featured_by_posts),
"pages" => (values of featured_by_pages)
]
]
I don't know if it can be done while getting data from database. That's why I tried to add the codes down below in index function on my API controller to produce formatted item of picture.
$relations = ["tags", "posts", "products", "featuredByPosts", "featuredByProducts", "featuredByPages"];
$pictures = Picture::with($relations)->get();
foreach ($pictures as $picture) {
$featureds = ["posts", "products", "pages"];
$key = "featured_by";
$picture[$key] = [];
foreach ($featureds as $featured) {
$oldKey = "{$key}_{$featured}";
$picture[$key][$featured] = $picture[$oldKey]; //This line produces the error
unset($picture[$oldKey]);
}
}
//ERROR: Indirect modification of overloaded element of App\Picture has no effect.
I don't understand what that means since the think. I searched this error and found some answers, but I couldn't make it work. So I hope someone can help. Thanks.
Upvotes: 1
Views: 57
Reputation: 66
You should use the eloquent API resources: https://laravel.com/docs/7.x/eloquent-resources
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class PictureResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'featured_by' => [
'posts' => $this->featuredByPost,
'products' => $this->featuredByProduct,
],
];
}
}
Your controller:
return new PictureResource(Picture::find(1));
Upvotes: 1