I am building an API using Resources. I have a Product (Chocolate Cake) that can be linked to a Property (Allergies) that has Properties_property (Glutten) that need to be shown in different orders for every product.
product <---[many-to-many] ---> properties
^ ^
| |
[many-to-many]--> properties_property --[belongs-to]
(pivot table)
position
The tables look like this:
products:
id
name
product_property (first pivot table)
product_id
property_id
properties:
id
name
properties_properties
id
name
product_properties_property (this is the pivot table witht the value)
product_id
properties_property_id
position
The aspired JSON out put of https://localhost/product would be :
{
"product": [{
"product_id": 1,
"name": "Choco Cake",
"properties": [{
"property_id": 1,
"name": "Allergies",
"properties_properties": [{
"properties_property_id": 1,
"name": "Gluten",
"position": 1
}]
}]
}]
}
The PropertiesProperty Model has a belongs to many relation in it like so:
public function products () {
return $this->belongsToMany(Product::class)->withPivot('position');
}
I throw all the products in there from the routes/api.php
Route::get('/product', function () {
return new ProductCollection(Product::all());
});
I have the following Resources: ProductResource, PropertyResource and PropertiesPropertyResource. The resources link to one another like so:
return [
'product_id' => $this->product_id,
'name' => $this->name,
'properties' => ProductsPropertyResource::collection($this->properties)
];
In the Resource of Properties_property I would like to access the position field of the pivot table. How do I go about this? Idealy my App\Http\Resource\PropertiesPropertyResourse.php would look something like:
return [
'properties_property_id' => $this->id,
'name' => $this->name,
'position' => $this->products->pivot->position
];
But this returns an "Property[pivot] does not exist on this collection"
I can write an sql in my PropertiesPropertyResource.php to get it like so:
return [
...
'position' => $this->products->where('id', $this->product_id)->first()->pivot->position
],
This does a lot of extra loading! The problem (I think) is that I want to access the data on the pivot table in the resource from the parent Resource (ProperiesProperty) not the child(Product) like you would usually do. Is there not a more Laravel-like method to do this?
REQUESTED INFO: There are about 230 connections in the pivot table currently, so this should not be a big deal.
UPDATE:
I found this question and I tried the solution:
'position' => $this->whenPivotLoaded ('product_properties_property', function () {
return $this->pivot->position;
}),
but here the position key didn't even show up in the Json of the /product endpoint. I am starting to suspect that you need to fill these values with the SQL that you put in the controller or (in my case) the routes/api.php file.