Closed denisgoryaynov closed 2 years ago
This is the code that loads relations in user factories. It calls the has$Relation
method in the factory. I'm not sure how or what else it should be doing🤔 Should it also be calling load()
?
Also, the factories are by default persisted to the database, so it may not be a memory issue.
Hi, after following you replies I tried to play around with the code and it seems that calling load($relations) line 189 in scribe/src/Extracting/Strategies/Responses/UseApiResourceTags.php
does the trick:
try {
// Before
// return $factory->create();
//After
return $factory->create()->load($relations);
} catch (Throwable $e) {
// If there was no working database, ->create() would fail. Try ->make() instead
return $factory->make();
}
But it doesn't seem to work when usign make() and leads to the command crashing.
I also found out that with()
doesn't work on models after they have been queried from database (even with production data), for example:
// In this case the relation with the organization object doesn't get loaded
// and calling $this->whenLoaded('organization') doesn't return the organization
public function show(User $user): UserResource
{
$user->with('organization');
return new UserResource($user);
}
/* Result
{
"data": {
"id": 1,
"name": "3d858092-e094-3d4e-8087-3b18dbec35b5",
"created_at": "2009-08-04T17:42:10.000000Z",
"updated_at": "1972-05-11T03:41:39.000000Z"
}
}
*/
But when using load()
the resource is created correctly:
// This works as intended
public function show(User $user): UserResource
{
$user->load('organization');
return new UserResource($user);
}
/* Result
{
"data": {
"id": 1,
"name": "3d858092-e094-3d4e-8087-3b18dbec35b5",
"created_at": "2009-08-04T17:42:10.000000Z",
"updated_at": "1972-05-11T03:41:39.000000Z",
"organization": {
"id": 1,
"name": "Murazik, Sporer and Glover",
"created_at": "2021-09-14T14:52:07.000000Z",
"updated_at": "2021-09-14T14:52:07.000000Z"
}
}
}
*/
So I suppose that this is just laravel handling relationships differently before/after query and that you are correct by saying that adding load()
should be enough to fix this
Also noticed this issue, good work finding a solution! Will this be implemented soon, or do you want me to create a PR? @shalvah
@johannesss PRs welcome. Also not sure, but #417 might be related.
I have the following code in my api resource
UserResource
:And the following code in my
UserFactory
:And this is the comment in my
UserController
:What I expect from my resource is the following result:
But what happens instead is I get:
If i use
$user->load('organization')
on the$user
object created by the factory I can successfully see that the relationship is present inside therelations
field of the Eloquent Model and theUserResource
successfully generates the expected output, but if I use$user->with('organization')
on the$user
object created by the factory therelations
field is empty, so maybe it has something to do with the way factories load the relations in memory?If I remove
UseFactory
from myUser
model scribe can successfully generate the expected documentation (by calling User::first() as I understand from the documentation).My environment:
php -v
): 7.4.23composer show laravel/framework
orcomposer show laravel/lumen-framework
): Laravel Framework 8.60.0composer show knuckleswtf/scribe
): 3.10.2My Scribe config (minus the comments):
Additional info: