Closed Synchro closed 2 years ago
Can you describe/explain regarding "I have some reciprocal BelongsToMany model relations (with a custom model for the join) that are set up like this:"
We already have dusk tests setup with similar structure without any issue and I don't believe the example above is enough to understand the issue.
Can you submit a full reproducing repository similar to https://github.com/nova-issues
#0 vendor/laravel/nova/src/ResolvesFields.php(962): Laravel\Nova\Resource->pivotFieldsFor(Object(Laravel\Nova\Http\Requests\ResourceIndexRequest), 'scans')
#1 vendor/laravel/framework/src/Illuminate/Collections/Traits/EnumeratesValues.php(482): Laravel\Nova\Resource->Laravel\Nova\{closure}(Array, true)
#2 vendor/laravel/nova/src/ResolvesFields.php(119): Illuminate\Support\Collection->when(true, Object(Closure))
#3 vendor/laravel/nova/src/ResolvesFields.php(150): Laravel\Nova\Resource->peekableFieldsCollection(Object(Laravel\Nova\Http\Requests\ResourceIndexRequest))
#4 vendor/laravel/nova/src/Fields/Peekable.php(85): Laravel\Nova\Resource->peekableFieldsCount(Object(Laravel\Nova\Http\Requests\ResourceIndexRequest))
#5 vendor/laravel/nova/src/Fields/BelongsTo.php(533): Laravel\Nova\Fields\BelongsTo->hasFieldsToPeekAt(Object(Laravel\Nova\Http\Requests\ResourceIndexRequest))
#6 vendor/laravel/framework/src/Illuminate/Support/helpers.php(377): Laravel\Nova\Fields\BelongsTo->Laravel\Nova\Fields\{closure}(Object(Laravel\Nova\Http\Requests\ResourceIndexRequest))
#7 vendor/laravel/nova/src/Fields/BelongsTo.php(542): with(Object(Laravel\Nova\Http\Requests\ResourceIndexRequest), Object(Closure))
#8 [internal function]: Laravel\Nova\Fields\BelongsTo->jsonSerialize()
I don't understand how using BelongsToMany
ends up with BelongsTo
. Did you setup the fields correctly?
We have a similar error with a "MorphToMany" relation since the update to 4.6.1
. (but were not on 4.6
before so it may be that the problem came with 4.6
)
@korridor can you submit reproducing code?
I just tested it again and the problem started with version 4.16.0
. With 4.15.2
this error disappears.
We have two models (names changed) SomeModel
and OtherModel
that are connected via a polymorph many-to-many relation to a model GeneralModel
.
// General Model
public function someModels(): MorphToMany|SomeModel
{
return $this->morphedByMany(SomeModel::class, 'fieldable', 'custom_table_name');
}
public function otherModels(): MorphToMany|OtherModel
{
return $this->morphedByMany(OtherModel::class, 'fieldable', 'custom_table_name');
}
// Fields in General Model Nova Resource
MorphedByMany::make('Used By Some Models', 'someModels', SomeModel::class),
MorphedByMany::make('Used By Other Models', 'otherModels', OtherModel::class),
// Other Model
public function generalModels(): MorphToMany|GeneralModel
{
return $this->morphToMany(
GeneralModel::class,
'fieldable',
'custom_table_name',
);
}
// Fields in Other Model Nova Resource
MorphToMany::make('General Models', 'generalModels', GeneralModel::class),
The SomeModel
model and Nova resource look basically the same and the error happens for both of them.
The error happens if we go to the detail page of a GeneralModel
in the request that loads the relations for SomeModel
and OtherModels
.
{
"message": "Call to a member function settingsFields() on null",
"exception": "Error",
"file": "/var/www/html/vendor/laravel/nova/src/ResolvesFields.php",
"line": 803
}
I expect that is because it's using a custom pivot model which contains a pair of BelongsTo
relations:
class ProductScan extends Pivot
{
public $timestamps = false;
protected $fillable = [
'scan_id',
'product_id',
'is_carrier',
'orderable_id',
];
protected $casts = [
'is_carrier' => 'boolean',
];
public function scan(): BelongsTo
{
return $this->belongsTo(
Scan::class
);
}
public function product(): BelongsTo
{
return $this->belongsTo(
Product::class
);
}
}
Looking at the docs, these manual relations may not be necessary any more, but regardless, they work fine in 4.15.
@korridor can you confirm it's related to having BelongsTo
/MorphTo
under MorphToMany
pivot model? I don't see you're having any using()
or indication of that.
@crynobone We are not using custom pivot models for the relationships that are causing the problem.
It's taken a bit of time writing the below, so there are newer messages above now. I'll still post this, in case it's of help.
I have a larger, very custom Nova and Laravel project, and isn't able to reproduce this either.
I also explicitly tested the Boolean
field, as that was given in the example.
I've tested in both 4.15.2, and 4.16.1.
So it's also hard to help out without more details (like reproducing repo), as well.
I tried removing the BelongsTo
methods in my pivot model, and things stayed working in 4.15, so it seems they are indeed unnecessary. Curiously, I'm finding the relation in Nova 4.16 breaks in one direction but not the other, so scan->products
fails, but the corresponding product->scans
works. All the fields involved are using default conventions – scan_id, product_id, etc.
Notably, the stack trace still mentions BelongsTo
even after removing those manual relations from my pivot model, suggesting it does the same thing internally.
Eliminating more things – removing the pivot fields from the Nova resources doesn't change anything.
I'm having lots of issues with 4.16.1 related to BelongsTo. It seems to cause issues when a row has a BelongsTo that is null. Instead of aborting loading the relation, it appears to try and load it anyway even though it's null. I suspect it's related to the new peeking behaviour but I tried to disable that with noPeeking()
and it doesn't seem help.
Edit: Reverting back to 4.15.2 makes all errors go away.
@Synchro can you share the full error log after removing pivot fields?
This is with no BelongsTo
relations in the pivot model. and no pivot fields in the resources:
[2022-10-18 13:55:21] local.ERROR: Call to a member function scans() on null {"userId":1,"exception":"[object] (Error(code: 0): Call to a member function scans() on null at vendor/laravel/nova/src/ResolvesFields.php:803)
[stacktrace]
#0 vendor/laravel/nova/src/ResolvesFields.php(962): Laravel\Nova\Resource->pivotFieldsFor(Object(Laravel\Nova\Http\Requests\ResourceIndexRequest), 'scans')
#1 vendor/laravel/framework/src/Illuminate/Collections/Traits/EnumeratesValues.php(482): Laravel\Nova\Resource->Laravel\Nova\{closure}(Array, true)
#2 vendor/laravel/nova/src/ResolvesFields.php(119): Illuminate\Support\Collection->when(true, Object(Closure))
#3 vendor/laravel/nova/src/ResolvesFields.php(150): Laravel\Nova\Resource->peekableFieldsCollection(Object(Laravel\Nova\Http\Requests\ResourceIndexRequest))
#4 vendor/laravel/nova/src/Fields/Peekable.php(85): Laravel\Nova\Resource->peekableFieldsCount(Object(Laravel\Nova\Http\Requests\ResourceIndexRequest))
#5 vendor/laravel/nova/src/Fields/BelongsTo.php(533): Laravel\Nova\Fields\BelongsTo->hasFieldsToPeekAt(Object(Laravel\Nova\Http\Requests\ResourceIndexRequest))
#6 vendor/laravel/framework/src/Illuminate/Support/helpers.php(377): Laravel\Nova\Fields\BelongsTo->Laravel\Nova\Fields\{closure}(Object(Laravel\Nova\Http\Requests\ResourceIndexRequest))
#7 vendor/laravel/nova/src/Fields/BelongsTo.php(542): with(Object(Laravel\Nova\Http\Requests\ResourceIndexRequest), Object(Closure))
#8 [internal function]: Laravel\Nova\Fields\BelongsTo->jsonSerialize()
#9 vendor/laravel/framework/src/Illuminate/Http/JsonResponse.php(87): json_encode(Array, 0)
#10 vendor/symfony/http-foundation/JsonResponse.php(54): Illuminate\Http\JsonResponse->setData(Array)
#11 vendor/laravel/framework/src/Illuminate/Http/JsonResponse.php(32): Symfony\Component\HttpFoundation\JsonResponse->__construct(Array, 200, Array, false)
#12 vendor/laravel/framework/src/Illuminate/Routing/ResponseFactory.php(99): Illuminate\Http\JsonResponse->__construct(Array, 200, Array, 0)
#13 vendor/laravel/nova/src/Http/Resources/Resource.php(41): Illuminate\Routing\ResponseFactory->json(Array)
#14 vendor/laravel/nova/src/Http/Controllers/ResourceIndexController.php(19): Laravel\Nova\Http\Resources\Resource->toResponse(Object(Laravel\Nova\Http\Requests\ResourceIndexRequest))
#15 vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): Laravel\Nova\Http\Controllers\ResourceIndexController->__invoke(Object(Laravel\Nova\Http\Requests\ResourceIndexRequest), 'products')
#16 vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(45): Illuminate\Routing\Controller->callAction('__invoke', Array)
#17 vendor/laravel/framework/src/Illuminate/Routing/Route.php(262): Illuminate\Routing\ControllerDispatcher->dispatch(Object(Illuminate\Routing\Route), Object(Laravel\Nova\Http\Controllers\ResourceIndexController), '__invoke')
#18 vendor/laravel/framework/src/Illuminate/Routing/Route.php(205): Illuminate\Routing\Route->runController()
#19 vendor/laravel/framework/src/Illuminate/Routing/Router.php(721): Illuminate\Routing\Route->run()
#20 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\Routing\Router->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#21 vendor/laravel/nova/src/Http/Middleware/Authorize.php(18): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#22 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Laravel\Nova\Http\Middleware\Authorize->handle(Object(Illuminate\Http\Request), Object(Closure))
#23 vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php(44): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#24 vendor/laravel/nova/src/Http/Middleware/Authenticate.php(31): Illuminate\Auth\Middleware\Authenticate->handle(Object(Illuminate\Http\Request), Object(Closure), 'web')
#25 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Laravel\Nova\Http\Middleware\Authenticate->handle(Object(Illuminate\Http\Request), Object(Closure))
#26 vendor/laravel/nova/src/Http/Middleware/BootTools.php(20): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#27 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Laravel\Nova\Http\Middleware\BootTools->handle(Object(Illuminate\Http\Request), Object(Closure))
#28 vendor/laravel/nova/src/Http/Middleware/DispatchServingNovaEvent.php(24): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#29 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Laravel\Nova\Http\Middleware\DispatchServingNovaEvent->handle(Object(Illuminate\Http\Request), Object(Closure))
#30 vendor/inertiajs/inertia-laravel/src/Middleware.php(92): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#31 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Inertia\Middleware->handle(Object(Illuminate\Http\Request), Object(Closure))
#32 vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(50): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#33 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\Routing\Middleware\SubstituteBindings->handle(Object(Illuminate\Http\Request), Object(Closure))
#34 vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(78): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#35 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\Foundation\Http\Middleware\VerifyCsrfToken->handle(Object(Illuminate\Http\Request), Object(Closure))
#36 vendor/laravel/framework/src/Illuminate/Session/Middleware/AuthenticateSession.php(58): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#37 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\Session\Middleware\AuthenticateSession->handle(Object(Illuminate\Http\Request), Object(Closure))
#38 vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#39 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\View\Middleware\ShareErrorsFromSession->handle(Object(Illuminate\Http\Request), Object(Closure))
#40 vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#41 vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\Session\Middleware\StartSession->handleStatefulRequest(Object(Illuminate\Http\Request), Object(Illuminate\Session\Store), Object(Closure))
#42 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\Session\Middleware\StartSession->handle(Object(Illuminate\Http\Request), Object(Closure))
#43 vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#44 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse->handle(Object(Illuminate\Http\Request), Object(Closure))
#45 vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(67): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#46 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\Cookie\Middleware\EncryptCookies->handle(Object(Illuminate\Http\Request), Object(Closure))
#47 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#48 vendor/laravel/framework/src/Illuminate/Routing/Router.php(723): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#49 vendor/laravel/framework/src/Illuminate/Routing/Router.php(698): Illuminate\Routing\Router->runRouteWithinStack(Object(Illuminate\Routing\Route), Object(Illuminate\Http\Request))
#50 vendor/laravel/framework/src/Illuminate/Routing/Router.php(662): Illuminate\Routing\Router->runRoute(Object(Illuminate\Http\Request), Object(Illuminate\Routing\Route))
#51 vendor/laravel/framework/src/Illuminate/Routing/Router.php(651): Illuminate\Routing\Router->dispatchToRoute(Object(Illuminate\Http\Request))
#52 vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(167): Illuminate\Routing\Router->dispatch(Object(Illuminate\Http\Request))
#53 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\Foundation\Http\Kernel->Illuminate\Foundation\Http\{closure}(Object(Illuminate\Http\Request))
#54 vendor/laravel/nova/src/Http/Middleware/ServeNova.php(23): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#55 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Laravel\Nova\Http\Middleware\ServeNova->handle(Object(Illuminate\Http\Request), Object(Closure))
#56 vendor/barryvdh/laravel-debugbar/src/Middleware/InjectDebugbar.php(66): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#57 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Barryvdh\Debugbar\Middleware\InjectDebugbar->handle(Object(Illuminate\Http\Request), Object(Closure))
#58 vendor/fideloper/proxy/src/TrustProxies.php(57): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#59 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Fideloper\Proxy\TrustProxies->handle(Object(Illuminate\Http\Request), Object(Closure))
#60 vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#61 vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle(Object(Illuminate\Http\Request), Object(Closure))
#62 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull->handle(Object(Illuminate\Http\Request), Object(Closure))
#63 vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#64 vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle(Object(Illuminate\Http\Request), Object(Closure))
#65 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\Foundation\Http\Middleware\TrimStrings->handle(Object(Illuminate\Http\Request), Object(Closure))
#66 vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#67 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\Foundation\Http\Middleware\ValidatePostSize->handle(Object(Illuminate\Http\Request), Object(Closure))
#68 vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(86): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#69 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance->handle(Object(Illuminate\Http\Request), Object(Closure))
#70 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#71 vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(142): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#72 vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(111): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(Object(Illuminate\Http\Request))
#73 public/index.php(53): Illuminate\Foundation\Http\Kernel->handle(Object(Illuminate\Http\Request))
#74 server.php(21): require_once('...')
#75 {main}
"}
If the BelongsToMany
field no longer has fields()
, it is impossible to reach the error line 803 on ResolvesFields
.
It may be a relation on the same model elsewhere in my schema, however, since all the calls in the stack are in vendor/
, I can't tell what it's tripping up on.
also have similiar issues with null values since 1.16 like @juse-less
@Synchro in your app, does/can Product
belongs to another Product
?
Aha! Yes – products can act as containers for other products. I commented out a self-referencing BelongsTo
field in the Product
Nova resource, and the error goes away, so I think you're onto something there.
I have the same problem with a resource (1) that has a BelongsTo relationship to a resource (2) with a BelongsToMany relationship. When resource 1 is used with a HasMany relationship on yet another resource (0), I get the same error as the op.
Resource 0 -> hasMany -> Resource 1 -> belongsTo -> Resource 2 -> BelongsToMany -> Resource 3
I suspect it has something to do with determining if there are peekable fields for resource 2.
I solved it for now by defining a fieldsForPeeking
method on resource 2, where I do not include any BelongsToMany fields.
Hi, I'm getting same kind error with 'HasMany' and 'BelongsToMany' fields, strange thing is not always get the errors some times get the errors like this
and this errors getting only on view mode
I'm using "laravel/nova": "4.15.2", and "laravel/framework": "^8.75",
here how I used it
`HasMany::make('Members'),
BelongsToMany::make('events')`
and
`public function members()
{
return $this->hasMany(Member::class);
}
public function events() : BelongsToMany
{
return $this->belongsToMany(
Event::class,
'events_segments'
);
}`
Hi, I'm getting same kind error with 'HasMany' and 'BelongsToMany' fields, strange thing is not always get the errors some times get the errors like this
and this errors getting only on view mode
I'm using "laravel/nova": "4.15.2", and "laravel/framework": "^8.75",
here how I used it
`HasMany::make('Members'), BelongsToMany::make('events')` and `public function members() { return $this->hasMany(Member::class); } public function events() : BelongsToMany { return $this->belongsToMany( Event::class, 'events_segments' ); }`
Looks this is happened me because of some times env file not reading, so APP_KEY was empty and getting error, so db connection not there and got the error, I guess. after set the 'key' => env('APP_KEY','base64:my_app_key') in app.php does not get the errors with has many and other relation fields.
Hi, I'm getting same kind error with 'HasMany' and 'BelongsToMany' fields, strange thing is not always get the errors some times get the errors like this and this errors getting only on view mode I'm using "laravel/nova": "4.15.2", and "laravel/framework": "^8.75", here how I used it
`HasMany::make('Members'), BelongsToMany::make('events')` and `public function members() { return $this->hasMany(Member::class); } public function events() : BelongsToMany { return $this->belongsToMany( Event::class, 'events_segments' ); }`
Looks this is happened me because of some times env file not reading, so APP_KEY was empty and getting error, so db connection not there and got the error, I guess. after set the 'key' => env('APP_KEY','base64:my_app_key') in app.php does not get the errors with has many and other relation fields.
sad story, error still there
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Description:
I have some reciprocal
BelongsToMany
model relations (with a custom model for the join) that are set up like this:In Nova:
and
In 4.15, this works fine – in my
scans
resource I see a list ofproduct
s, and vice versa. In 4.16 I get a crash:I had thought I had found some records which did not cause this crash, however, I've now spotted that the error only appears when the relation shows the last page of results, so it appears all the time for records that have less than 5 related records, but not until you page to the last set if there are more than that. I feel this is a valuable clue!
I've been looking at the changelog, but I can't spot what might have affected this.