【问题标题】:Laravel: route model binding exception handling in ajax requestLaravel:ajax请求中的路由模型绑定异常处理
【发布时间】:2020-07-19 14:22:42
【问题描述】:

Laravel 7.x 版

我正在通过 ajax 请求提交 createedit 方法,并且工作正常。但是,在我的应用程序中有一个依赖于父模块的模块,例如:EmployeeEmployeeEmergency。所以我在create方法中添加了Employee $Employee参数和route来处理这个请求。

但是,如果Employee 标识符正确,则可以正常工作。但是,如果标识符无效,则会引发异常。

{
    "message": "No query results for model [App\\Employee] $arrayModel->token",
    "exception": "Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException",
    ...
}

我可以通过手动删除route model binding 和验证Employee 来处理此异常。但是,这只会不必要地增加代码。

我想用适当的响应来处理这个异常,比如Employee identifier is invalid 或类似的东西来通知用户并防止错误。

Employee.php

class Employee extends Model
{
    ...

    public function getRouteKeyName()
    {
        return 'token';
    }

    ...
}

EmployeeEmergencyController.php

use App\Employee;
use App\EmployeeEmergency;

class EmployeeEmergencyController extends Controller
{
    public function create(Employee $employee)
    {
        ...
    }
}

Web.php

Route::get('employee-emergency/create/{employee}', 'EmployeeEmergencyController@create')
    ->name('admin.employee-emergency.create');

有没有开箱即用的解决方案..?

【问题讨论】:

    标签: laravel model binding routes


    【解决方案1】:

    感谢@Rob,这是我的最终代码。

    RouteServiceProvider.php

    public function boot()
    {
        parent::boot();
    
        Route::bind('employee', function ($token) {
            return \App\Employee::where('token', $token)->first() ?? false;
        });
    }
    

    在控制器中

    public function create($employee)
    {
      if($employee == false)
      {
        # setting success message
        session()->flash('warning', 'Could not find the reference for the given `Employee`');
    
        # redirecting
        return response()->json([
          'success' => false
        ], Response::HTTP_BAD_REQUEST);
      }
    
      ...
    }
    

    但是,此代码对我有用。但是,它还能改进吗..?

    【讨论】:

    • 是的@Rob你是对的,实际上我首先尝试过。我需要将其重定向到带有警告消息的index 页面,但由于应用程序的要求是使用ajax 加载和提交表单,因此它无法按我的要求工作。因此,我不得不采取这种方法。如果您认为可以根据这种情况对其进行改进,那么请发布更好的方法。对此,我真的非常感激。谢谢:)
    【解决方案2】:

    首先,请注意,您收到的错误比平时大得多,因为您在 .env 中将 APP_DEBUG 设置为 trueAPP_ENV 设置为 local,如果 APP_DEBUGfalse 和 APP_ENV= 生产,错误应该减少到普通的 404。

    其次,如果您查看文档:https://laravel.com/docs/6.x/routing#explicit-binding

    你可以看到你可以像这样自定义行为:

    //App\Providers\RouteServiceProvider.php
    public function boot()
    {
        parent::boot();
    
        Route::bind('employee', function ($id) {
            $employee = App\Employee::where('id', $id)->first();
            if (empty($employee)) {
                throw new \Exception('Employee not found');
            }
            return $employee
        });
    }
    

    编辑:

    • 更新了 laravel 链接
    • 更新了答案本身

    【讨论】:

    • 现在我得到了这个Declaration of App\Providers\RouteServiceProvider::boot(App\Providers\Router $router) should be compatible with Illuminate\Foundation\Support\Providers\RouteServiceProvider::boot()
    • 我的错,您不再需要引导参数中的Router $router。我会更新我的答案。
    • 它达到了employee.show 方法,甚至停止加载。我需要这个来打employee-emergency/create/{employee}。但是,我尝试将 employee 更改为 employeeEmergency 但没有运气,每次都出现相同的错误
    • 要明确一点:你在 routeServiceProvider 'employee' 中绑定的变量名,就是你在路由中使用的变量名,比如employee-emergency/create/{employee}。每个包含{employee} 的路由都可以使用它。所以你说的事情没有意义。您可以发布您现在拥有的代码吗?
    • 谢谢@Rob。实际上我是第一次使用这个 Route Model Binding,所以这对我来说有点困难。但是,它现在工作。我很快就会放上最终的代码。再次感谢:)
    猜你喜欢
    • 2015-12-30
    • 1970-01-01
    • 1970-01-01
    • 2018-08-13
    • 1970-01-01
    • 2020-05-27
    • 2019-10-04
    • 1970-01-01
    • 2021-08-31
    相关资源
    最近更新 更多