String as primary key causes issues with redirection and action_events #4116
-
Description:1. Creating models having a string as primary key 2. Updating models having a string as primary key 3. Deleting models having a string as primary key Detailed steps to reproduce the issue on a fresh Nova installation:
|
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
|
First of all, most polymorphic relationships would either expect relationships with foreign keys to consistently be UUID or numeric ID. If all models in your application use UUID (string) as the primary key then you should be able to run the following: app('db.schema')->morphUsingUuids();This would tell Nova/Laravel to migrate If you have a mixed numeric ID and UUID combination you should either export the database migration and handle it on your own or completely disable return [
/*
|--------------------------------------------------------------------------
| Nova Action Resource Class
|--------------------------------------------------------------------------
|
| This configuration option allows you to specify a custom resource class
| to use for action log entries instead of the default that ships with
| Nova, thus allowing for the addition of additional UI form fields.
|
*/
'actions' => [
'resource' => null,
],
]; |
Beta Was this translation helpful? Give feedback.
-
|
Ironically, I only have the concern when I want to edit the nova_notifications with a Nova resource. I have this disabled, just for this one case. (destroy, force delete & restore) I created 3 controller:
<?php
namespace App\Http\Controllers\Nova;
use Laravel\Nova\Actions\Actionable;
use Laravel\Nova\Http\Requests\DeleteResourceRequest;
use Laravel\Nova\Nova;
use Laravel\Nova\URL;
class ResourceDestroyController extends \Laravel\Nova\Http\Controllers\ResourceDestroyController
{
/**
* Destroy the given resource(s).
*
* @param \Laravel\Nova\Http\Requests\DeleteResourceRequest $request
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
*/
public function __invoke(DeleteResourceRequest $request)
{
$request->chunks(150, function ($models) use ($request) {
$models->each(function ($model) use ($request) {
$this->deleteFields($request, $model);
$uses = class_uses_recursive($model);
if (in_array(Actionable::class, $uses) && ! in_array(SoftDeletes::class, $uses)) {
$model->actions()->delete();
}
$model->delete();
$request->resource()::afterDelete($request, $model);
if (is_int($model->getKey())) {
Nova::usingActionEvent(function ($actionEvent) use ($model, $request) {
$actionEvent->insert(
$actionEvent->forResourceDelete(Nova::user($request), collect([$model]))
->map->getAttributes()->all()
);
});
}
});
});
if ($request->isForSingleResource() && ! is_null($redirect = $request->resource()::redirectAfterDelete($request))) {
return response()->json([
'redirect' => URL::make($redirect),
]);
}
return response()->noContent(200);
}
}
<?php
namespace App\Http\Controllers\Nova;
use Laravel\Nova\Actions\Actionable;
use Laravel\Nova\Http\Requests\ForceDeleteResourceRequest;
use Laravel\Nova\Nova;
class ResourceForceDeleteController extends \Laravel\Nova\Http\Controllers\ResourceForceDeleteController
{
/**
* Force delete the given resource(s).
*
* @param \Laravel\Nova\Http\Requests\ForceDeleteResourceRequest $request
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
*/
public function __invoke(ForceDeleteResourceRequest $request)
{
$request->chunks(150, function ($models) use ($request) {
$models->each(function ($model) use ($request) {
$this->forceDeleteFields($request, $model);
if (in_array(Actionable::class, class_uses_recursive($model))) {
$model->actions()->delete();
}
$model->forceDelete();
$request->resource()::afterForceDelete($request, $model);
if (is_int($model->getKey())) {
Nova::usingActionEvent(function ($actionEvent) use ($model, $request) {
$actionEvent->insert(
$actionEvent->forResourceDelete(Nova::user($request), collect([$model]))
->map->getAttributes()->all()
);
});
}
});
});
if ($request->isForSingleResource() && ! is_null($redirect = $request->resource()::redirectAfterDelete($request))) {
return response()->json([
'redirect' => $redirect,
]);
}
return response()->noContent(200);
}
}
<?php
namespace App\Http\Controllers\Nova;
use Laravel\Nova\Http\Requests\RestoreResourceRequest;
use Laravel\Nova\Nova;
class ResourceRestoreController extends \Laravel\Nova\Http\Controllers\ResourceRestoreController
{
/**
* Restore the given resource(s).
*
* @param \Laravel\Nova\Http\Requests\RestoreResourceRequest $request
* @return \Illuminate\Http\Response
*/
public function __invoke(RestoreResourceRequest $request)
{
$request->chunks(150, function ($models) use ($request) {
$models->each(function ($model) use ($request) {
$model->restore();
if (is_int($model->getKey())) {
Nova::usingActionEvent(function ($actionEvent) use ($model, $request) {
$actionEvent->insert(
$actionEvent->forResourceRestore(Nova::user($request), collect([$model]))
->map->getAttributes()->all()
);
});
}
});
});
return response()->noContent(200);
}
}And bind these controllers in the public function boot(): void
{
app()->bind(\Laravel\Nova\Http\Controllers\ResourceDestroyController::class,
\App\Http\Controllers\Nova\ResourceDestroyController::class);
app()->bind(\Laravel\Nova\Http\Controllers\ResourceForceDeleteController::class,
\App\Http\Controllers\Nova\ResourceForceDeleteController::class);
app()->bind(\Laravel\Nova\Http\Controllers\ResourceRestoreController::class,
\App\Http\Controllers\Nova\ResourceRestoreController::class);
// |
Beta Was this translation helpful? Give feedback.
First of all, most polymorphic relationships would either expect relationships with foreign keys to consistently be UUID or numeric ID. If all models in your application use UUID (string) as the primary key then you should be able to run the following:
This would tell Nova/Laravel to migrate
action_eventsusingstring.If you have a mixed numeric ID and UUID combination you should either export the database migration and handle it on your own or completely disable
action_eventsby updatingconfig/nova.phpwith the following: