You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 11/Vue:软删除模型路由绑定强制删除时404错误

问题描述

在使用Laravel路由模型绑定对软删除的Recipe模型执行forceDelete()时,出现404 Not Found错误,仅在强制删除已软删除的模型时触发;恢复或软删除操作均正常。

已在edit方法中实现编辑已软删除模型时自动恢复的功能,该功能可正常运行:

RecipeController.php

// 此功能正常工作
public function edit(Recipe $recipe)
{
    Gate::authorize('update', $recipe);

    if ($recipe->trashed()) {
        $recipe->restore();
    }

    return Inertia::render('Recipes/Edit', [
        'recipe' => $recipe->load(['ingredients', 'steps', 'categories']),
        'categories' => Auth::user()->categories
    ]);
}

尝试在destroy方法的Gate::authorize()前添加dd($recipe),但仍直接返回404,说明路由模型绑定未找到对应模型。希望保留标准资源路由,让destroy方法自动判断执行永久删除还是软删除,询问是否必须新增方法仅传入ID处理强制删除。

相关配置及代码如下:

web.php

Route::resource('/recipes', RecipeController::class)->withTrashed();

RecipeController.php

// 软删除正常,但强制删除已软删除模型时返回404
public function destroy(Recipe $recipe)
{
   Gate::authorize('delete', $recipe);
        
   if ($recipe->trashed()) {
       $recipe->forceDelete();
       Storage::deleteDirectory('recipe-images/'.$recipe->id);
   } else {
       $recipe->delete();
   }
}

Index.vue

<Link :href="route('recipes.destroy', recipe)" method="delete" as="button" class="relative inline-flex w-0 flex-1 items-center justify-center gap-x-3 rounded-br-lg border border-transparent py-3 text-sm font-semibold text-gray-900">
    <TrashIcon class="h-5 w-5 text-red-400" aria-hidden="true" />
</Link>

路由列表输出

DELETE recipes/{recipe} recipes.destroy › RecipeController@destroy

控制台错误

DELETE http://127.0.0.1:8000/recipes/9c8fa4c7-8723-4ca4-8468-5968ae7c02e3 404 (Not Found)
解决方案

问题根源:Laravel隐式路由模型绑定默认仅查询未被软删除的记录,当尝试通过路由绑定获取已软删除的模型时,系统会返回404,因为找不到匹配的未删除记录。

以下几种方案可解决问题,无需新增额外方法:

方案1:修改路由,单独为destroy方法指定withTrashed

将原资源路由拆分为普通资源路由+单独的destroy路由,确保destroy路由的参数包含软删除模型:

// 先注册除destroy外的所有资源路由
Route::resource('/recipes', RecipeController::class)->except(['destroy']);
// 单独注册destroy路由并添加withTrashed约束
Route::delete('/recipes/{recipe}', [RecipeController::class, 'destroy'])->withTrashed();

方案2:在控制器destroy方法中手动查询含软删除的模型

放弃隐式路由模型绑定,改用显式查询获取包含软删除的模型:

public function destroy($id)
{
    // 显式查询包含软删除的模型
    $recipe = Recipe::withTrashed()->findOrFail($id);
    Gate::authorize('delete', $recipe);
        
    if ($recipe->trashed()) {
        $recipe->forceDelete();
        Storage::deleteDirectory('recipe-images/'.$recipe->id);
    } else {
        $recipe->delete();
    }
    
    // 添加响应返回,比如重定向或Inertia响应
    return redirect()->route('recipes.index');
}

方案3:修改模型的路由绑定逻辑,全局包含软删除记录

在Recipe模型中重写路由绑定解析方法,让所有路由模型绑定都包含软删除的记录:

// Recipe.php模型文件
public function resolveRouteBinding($value, $field = null)
{
    return $this->withTrashed()
        ->where($field ?? $this->getRouteKeyName(), $value)
        ->firstOrFail();
}

注意:此方案会影响所有使用该模型的路由绑定,若部分场景不需要包含软删除模型,需谨慎使用。

内容的提问来源于stack exchange,提问作者GazSte

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 16:43:12