mikebronner / laravel-model-caching

Eloquent model-caching made easy.
MIT License
2.24k stars 214 forks source link

Undefined property exception when updating a BelongsToMany relationship #360

Closed joeyrush closed 4 years ago

joeyrush commented 4 years ago

Describe the bug I get the following exception when trying to call update on a BelongsToMany relationship

Undefined property: GeneaLabs\LaravelModelCaching\CachedBelongsToMany::$model

Eloquent Query Very easy to recreate with a simple pivot table setup (a company belongs to many currencies through the company_currencies table).

Important Note: the exception is only thrown when the cachable trait is on both the Company and the Currency models.

class Currency extends \Illuminate\Database\Eloquent\Model
{
    use \GeneaLabs\LaravelModelCaching\Traits\Cachable;
}

class Company extends \Illuminate\Database\Eloquent\Model
{
    use \GeneaLabs\LaravelModelCaching\Traits\Cachable;

    public function currencies()
    {
        return $this->belongsToMany(\Hub\Models\Currency::class, 'company_currencies');
     }
}

$company = Company::first();

// The following line throws an exception:
$company->currencies()->update(['company_currencies.is_primary' => 1]);

If I remove the Cachable trait, the update query runs as expected. (Note: exception is thrown regardless of whether I specify a column on the pivot table or a column on the currencies table for the update)

Stack Trace

[2020-07-08 17:41:52] local.ERROR: Undefined property: GeneaLabs\LaravelModelCaching\CachedBelongsToMany::$model {"userId":1,"exception":"[object] (ErrorException(code: 0): Undefined property: GeneaLabs\\LaravelModelCaching\\CachedBelongsToMany::$model at /Users/joerushton/projects/newtickets/vendor/genealabs/laravel-model-caching/src/Traits/Buildable.php:205)
[stacktrace]
#0 [internal function]: Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleError(8, 'Undefined prope...', '/Users/joerusht...', 205)
#1 /Users/joerushton/projects/newtickets/vendor/honeybadger-io/honeybadger-php/src/Handlers/ErrorHandler.php(43): call_user_func(Array, 8, 'Undefined prope...', '/Users/joerusht...', 205)
#2 /Users/joerushton/projects/newtickets/vendor/genealabs/laravel-model-caching/src/Traits/Buildable.php(205): Honeybadger\\Handlers\\ErrorHandler->handle(8, 'Undefined prope...', '/Users/joerusht...', 205, Array)
#3 /Users/joerushton/projects/newtickets/packages/admin/routes/web.php(37): GeneaLabs\\LaravelModelCaching\\CachedBelongsToMany->update(Array)
#4 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Routing/Route.php(225): Illuminate\\Routing\\RouteFileRegistrar->{closure}()
#5 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Routing/Route.php(199): Illuminate\\Routing\\Route->runCallable()
#6 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Routing/Router.php(685): Illuminate\\Routing\\Route->run()
#7 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#8 /Users/joerushton/projects/newtickets/packages/core/app/Http/Middleware/SetLocale.php(29): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#9 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Core\\Http\\Middleware\\SetLocale->handle(Object(Illuminate\\Http\\Request), Object(Closure), 'admin')
#10 /Users/joerushton/projects/newtickets/vendor/honeybadger-io/honeybadger-laravel/src/Middleware/HoneybadgerContext.php(43): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#11 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Honeybadger\\HoneybadgerLaravel\\Middleware\\HoneybadgerContext->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#12 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(41): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#13 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Routing\\Middleware\\SubstituteBindings->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#14 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(76): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#15 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#16 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#17 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\View\\Middleware\\ShareErrorsFromSession->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#18 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(116): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#19 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(62): Illuminate\\Session\\Middleware\\StartSession->handleStatefulRequest(Object(Illuminate\\Http\\Request), Object(Illuminate\\Session\\Store), Object(Closure))
#20 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Session\\Middleware\\StartSession->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#21 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#22 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#23 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(66): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#24 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Cookie\\Middleware\\EncryptCookies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#25 /Users/joerushton/projects/newtickets/packages/admin/app/Http/Middleware/AdminMiddleware.php(43): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#26 /Users/joerushton/projects/newtickets/vendor/silber/bouncer/src/Database/Scope/Scope.php(216): Admin\\Http\\Middleware\\AdminMiddleware->Admin\\Http\\Middleware\\{closure}()
#27 /Users/joerushton/projects/newtickets/packages/admin/app/BouncerCompanyScope.php(23): Silber\\Bouncer\\Database\\Scope\\Scope->onceTo(1, Object(Closure))
#28 /Users/joerushton/projects/newtickets/packages/admin/app/Http/Middleware/AdminMiddleware.php(44): Admin\\BouncerCompanyScope->onceTo(1, Object(Closure))
#29 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Admin\\Http\\Middleware\\AdminMiddleware->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#30 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#31 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Routing/Router.php(687): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#32 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Routing/Router.php(662): Illuminate\\Routing\\Router->runRouteWithinStack(Object(Illuminate\\Routing\\Route), Object(Illuminate\\Http\\Request))
#33 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Routing/Router.php(628): Illuminate\\Routing\\Router->runRoute(Object(Illuminate\\Http\\Request), Object(Illuminate\\Routing\\Route))
#34 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Routing/Router.php(617): Illuminate\\Routing\\Router->dispatchToRoute(Object(Illuminate\\Http\\Request))
#35 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(165): Illuminate\\Routing\\Router->dispatch(Object(Illuminate\\Http\\Request))
#36 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}(Object(Illuminate\\Http\\Request))
#37 /Users/joerushton/projects/newtickets/vendor/inertiajs/inertia-laravel/src/Middleware.php(13): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#38 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Inertia\\Middleware->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#39 /Users/joerushton/projects/newtickets/vendor/barryvdh/laravel-debugbar/src/Middleware/InjectDebugbar.php(65): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#40 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Barryvdh\\Debugbar\\Middleware\\InjectDebugbar->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#41 /Users/joerushton/projects/newtickets/vendor/fruitcake/laravel-cors/src/HandleCors.php(37): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#42 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Fruitcake\\Cors\\HandleCors->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#43 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#44 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#45 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#46 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#47 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#48 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#49 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php(63): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#50 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#51 /Users/joerushton/projects/newtickets/vendor/fideloper/proxy/src/TrustProxies.php(57): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#52 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Fideloper\\Proxy\\TrustProxies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#53 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#54 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(140): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#55 /Users/joerushton/projects/newtickets/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(109): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter(Object(Illuminate\\Http\\Request))
#56 /Users/joerushton/projects/newtickets/public/index.php(55): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request))
#57 /Users/joerushton/.composer/vendor/laravel/valet/server.php(158): require('/Users/joerusht...')
#58 {main}
"} 

Environment

mikebronner commented 4 years ago

Thanks for reporting this. I will attempt to recreate and report back.

mikebronner commented 4 years ago

@joeyrush can you give release 0.8.10 a try and let me know how it works? Thanks!

joeyrush commented 4 years ago

Appears to be working.. Awesome job, thanks for the quick resolution!!

mikebronner commented 4 years ago

No problem, thanks for reporting it! :)