Open ashgibson opened 6 years ago
Any comment, update on this?
Same issue and I think I found the issue. As lazychaser said, this has been tested but for the case where you try to load the model with its ancestors/descendants. The issue arise when you try to eagerload the model with an intermediary relation like "category.ancestors", and here is why :
This is as far as I got for now. But if you're still on the issue (since you came back 8 months after your first post), it might be helpful. I'll try adding more information or even make PR if I find a solution.
It is still an issue but I have a fix which is working for my application. The fix does have potential performance issues but it is working for the moment.
In case anyone is interested, I have added some code to my CategoryResource class as follows:
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'lft' => $this->_lft,
'rgt' => $this->_rgt,
'children' => CategoryResource::collection($this->whenLoaded('children')),
'ancestors' => CategoryResource::collection($this->whenLoaded('ancestors', function() {
return $this->getAncestors();
}))
];
}
My ItemResource class does this
'category' => CategoryResource::make($this->whenLoaded('category')),
Because the scope_id is null the ancestors relationship is loaded but contains no data. This code does a lazy load of the ancestors for each item as Laravel loops through the collection and transforms the data with the resource. The getAncestors() applies the correct scoping.
I can confirm that this is an issue.
I'm attempting to implement nodes in https://laravel-json-api.readthedocs.io/en/latest/, but it's tricky to do with this bug.
Eager loading is done automatically in the library when loading related resourced (with the include parameter).
In Schema.php
I currently also have to use the work-around by calling the relationship directly, but that gives a ton of overhead...
return [
'descendants' => [
self::SHOW_SELF => true,
self::SHOW_RELATED => true,
self::SHOW_DATA => isset($includedRelationships['descendants']),
self::DATA => function () use ($resource) {
// Directly calling $resource->descendants does not work,
// cause of this issue https://github.com/lazychaser/laravel-nestedset/issues/271.
// @todo: this needs to be addressed at some point, since there's a lot of overhead when called with include.
return $resource->getDescendants();
},
],
]
I tried to xdebug this, but the internals make it pretty hard to follow. Of what I can tell, the relationship is accessed before there's actually data, so the scope parameter is null.
After some more digging I came up with a solution for this issue:
https://github.com/Ciaro/laravel-nestedset/commits/fix-scoped-relationships
@ashgibson have a look and see if that fixes the issue :)
I have a data structure with Products and Categories (nested set) but these models are scoped to an account_id. How can get a product and eager load the category and descendants or ancestors?
Due to the scope, I can see the query is adding scope with account_id = NULL.