dcat-admin icon indicating copy to clipboard operation
dcat-admin copied to clipboard

Can't save hasMany change by using Dcat\Admin\Form\Field\Tree

Open yuetyeelo2855 opened this issue 4 years ago • 0 comments

  • Laravel Version: 8.51.0
  • PHP Version: 7.4.16
  • Dcat Admin Version: 2.1.1-beta

Description:

I can't select child when using Tree in Form Editing, I using HasMany / BelongsTo in EntityA and EnityB. EntityA has many EntityB, EntityB belongs to EntityA. I can show the tree correctly, but I can't save the change of it.

Steps To Reproduce:

            $form->tree('entityB')
                ->nodes((new EntityB())->allNodes())
                ->setTitleColumn('title')
                ->customFormat(function ($v) {
                    $value = array_column($v, 'id');
                    return $value;
                });

Below error is shown when save the change of EntityA.

[2021-07-25 15:15:28] local.ERROR: array_key_exists() expects parameter 2 to be array, string given {"exception":"[object] (ErrorException(code: 0): array_key_exists() expects parameter 2 to be array, string given at /var/www/html/vendor/laravel/framework/src/Illuminate/Collections/Arr.php:155)
[stacktrace]
#0 [internal function]: Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleError()
#1 /var/www/html/vendor/laravel/framework/src/Illuminate/Collections/Arr.php(155): array_key_exists()
#2 /var/www/html/vendor/laravel/framework/src/Illuminate/Collections/Arr.php(253): Illuminate\\Support\\Arr::exists()
#3 /var/www/html/vendor/dcat/laravel-admin/src/Repositories/EloquentRepository.php(938): Illuminate\\Support\\Arr::forget()
#4 /var/www/html/vendor/dcat/laravel-admin/src/Repositories/EloquentRepository.php(538): Dcat\\Admin\\Repositories\\EloquentRepository->updateRelation()
#5 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php(29): Dcat\\Admin\\Repositories\\EloquentRepository->Dcat\\Admin\\Repositories\\{closure}()
#6 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php(388): Illuminate\\Database\\Connection->transaction()
#7 /var/www/html/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(261): Illuminate\\Database\\DatabaseManager->__call()
#8 /var/www/html/vendor/dcat/laravel-admin/src/Repositories/EloquentRepository.php(539): Illuminate\\Support\\Facades\\Facade::__callStatic()
#9 /var/www/html/vendor/dcat/laravel-admin/src/Form.php(816): Dcat\\Admin\\Repositories\\EloquentRepository->update()
#10 /var/www/html/vendor/dcat/laravel-admin/src/Http/Controllers/AdminController.php(141): Dcat\\Admin\\Form->update()
#11 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): Dcat\\Admin\\Http\\Controllers\\AdminController->update()
#12 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(45): Illuminate\\Routing\\Controller->callAction()
#13 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Route.php(254): Illuminate\\Routing\\ControllerDispatcher->dispatch()
#14 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Route.php(197): Illuminate\\Routing\\Route->runController()
#15 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(695): Illuminate\\Routing\\Route->run()
#16 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}()
#17 /var/www/html/vendor/dcat/laravel-admin/src/Http/Middleware/WebUploader.php(22): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#18 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Dcat\\Admin\\Http\\Middleware\\WebUploader->handle()
#19 /var/www/html/vendor/dcat/laravel-admin/src/Http/Middleware/Session.php(12): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#20 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Dcat\\Admin\\Http\\Middleware\\Session->handle()
#21 /var/www/html/vendor/dcat/laravel-admin/src/Http/Middleware/Permission.php(40): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#22 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Dcat\\Admin\\Http\\Middleware\\Permission->handle()
#23 /var/www/html/vendor/dcat/laravel-admin/src/Http/Middleware/Bootstrap.php(19): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#24 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Dcat\\Admin\\Http\\Middleware\\Bootstrap->handle()
#25 /var/www/html/vendor/dcat/laravel-admin/src/Http/Middleware/Pjax.php(23): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#26 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Dcat\\Admin\\Http\\Middleware\\Pjax->handle()
#27 /var/www/html/vendor/dcat/laravel-admin/src/Http/Middleware/Authenticate.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#28 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Dcat\\Admin\\Http\\Middleware\\Authenticate->handle()
#29 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(50): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#30 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Routing\\Middleware\\SubstituteBindings->handle()
#31 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(78): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#32 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken->handle()
#33 /var/www/html/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#34 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\View\\Middleware\\ShareErrorsFromSession->handle()
#35 /var/www/html/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#36 /var/www/html/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\\Session\\Middleware\\StartSession->handleStatefulRequest()
#37 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Session\\Middleware\\StartSession->handle()
#38 /var/www/html/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#39 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse->handle()
#40 /var/www/html/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(67): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#41 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Cookie\\Middleware\\EncryptCookies->handle()
#42 /var/www/html/vendor/dcat/laravel-admin/src/Http/Middleware/Application.php(15): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#43 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Dcat\\Admin\\Http\\Middleware\\Application->handle()
#44 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#45 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(697): Illuminate\\Pipeline\\Pipeline->then()
#46 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(672): Illuminate\\Routing\\Router->runRouteWithinStack()
#47 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(636): Illuminate\\Routing\\Router->runRoute()
#48 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(625): Illuminate\\Routing\\Router->dispatchToRoute()
#49 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(166): Illuminate\\Routing\\Router->dispatch()
#50 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}()
#51 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#52 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle()
#53 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull->handle()
#54 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#55 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle()
#56 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle()
#57 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#58 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle()
#59 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(86): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#60 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle()
#61 /var/www/html/vendor/fruitcake/laravel-cors/src/HandleCors.php(38): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#62 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Fruitcake\\Cors\\HandleCors->handle()
#63 /var/www/html/vendor/fideloper/proxy/src/TrustProxies.php(57): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#64 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Fideloper\\Proxy\\TrustProxies->handle()
#65 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#66 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(141): Illuminate\\Pipeline\\Pipeline->then()
#67 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(110): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter()
#68 /var/www/html/public/index.php(52): Illuminate\\Foundation\\Http\\Kernel->handle()
#69 /var/www/html/server.php(21): require_once('/var/www/html/p...')
#70 {main}
"} 

I'm using below code to solve the problem temporarily, please provide a long term solution for this bug.

            $form->saving(function (Form $form) {
                $model = $form->model();
                $entityB = array_map(function ($id) {
                    return intval($id, 10);
                }, explode(',', $form->entityB));
                $model->entityB->each(function (EntityB $entityB) {
                    $entityB->entityA()->dissociate()->save();
                });
                EntityB::whereIn('id', $entityB)->get()->each(function (EntityB $entityB) use ($model) {
                    $entityB->entityA()->associate($model)->save();
                });
                $form->deleteInput('entityB');
            });

yuetyeelo2855 avatar Jul 25 '21 15:07 yuetyeelo2855