laravel 绑定 区别_Laravel快速提示:模型路线绑定

laravel 绑定 区别

One of the great things that Laravel provides is the easy to use routing component. It offers simple URLs, parameters, grouping, naming and event guarding route groups, to name a few of the different options.

Laravel提供的重要功能之一是易于使用的路由组件。 它提供了简单的URL,参数,分组,命名和事件保护路由组,以列举一些不同的选项。

Laravel Logo

Let’s pretend we have a list of categories in a database, and the admin can manage categories from the back end. Here’s how your routes file should look like.

假设我们在数据库中有一个类别列表,管理员可以从后端管理类别。 这是您的路线文件的外观。

Route::group(['namespace' => 'Admin', 'prefix' => 'admin', 'middleware' => 'admin'], function () {
    Route::resource('categories', 'CategoriesController');
});

Inside your CategoriesController class, you’ll have the seven resource methods. Inside the edit action, we should check if the category being edited exists in the database, otherwise we redirect back with an error message.

CategoriesController类中,您将拥有七个资源方法。 在edit动作中,我们应该检查数据库中是否存在正在编辑的类别,否则我们将返回一条错误消息。

public function edit($id)
{
    $category = Category::find($id);
    if (!$category) {
        return redirect()->route('admin.categories.index')->withErrors([trans('errors.category_not_found')]);
    }

    // ...
}

模型绑定 (Model Binding)

This is the usual way of doing it, but Laravel also has a nicer way of optimizing this repetitive task called route model binding. You basically type hint the model name instead of the ID parameter.

这是通常的做法,但是Laravel还有一种更好的方法来优化此重复任务,称为路由模型绑定 。 基本上,您键入提示模型名称而不是ID参数。

If you list the available routes, it should look something like this.

如果您列出了可用的路线,它应该看起来像这样。

+--------+-----------+------------------------------------+------------------------------------+----------------------------------------------------------------------+-----------------+
| Domain | Method    | URI                                | Name                               | Action                                                               | Middleware      |
+--------+-----------+------------------------------------+------------------------------------+----------------------------------------------------------------------+-----------------+
|        | GET|HEAD  | admin/categories                   | admin.categories.index             | App\Http\Controllers\Admin\CategoriesController@index                | web,admin       |
|        | POST      | admin/categories                   | admin.categories.store             | App\Http\Controllers\Admin\CategoriesController@store                | web,admin       |
|        | GET|HEAD  | admin/categories/create            | admin.categories.create            | App\Http\Controllers\Admin\CategoriesController@create               | web,admin       |
|        | GET|HEAD  | admin/categories/{categories}      | admin.categories.show              | App\Http\Controllers\Admin\CategoriesController@show                 | web,admin       |
|        | PUT|PATCH | admin/categories/{categories}      | admin.categories.update            | App\Http\Controllers\Admin\CategoriesController@update               | web,admin       |
|        | DELETE    | admin/categories/{categories}      | admin.categories.destroy           | App\Http\Controllers\Admin\CategoriesController@destroy              | web,admin       |
|        | GET|HEAD  | admin/categories/{categories}/edit | admin.categories.edit              | App\Http\Controllers\Admin\CategoriesController@edit                 | web,admin       |

You can see that the routing parameter is {categories} which you can leave like that if you wish. However, Laravel provides an option to change it.

您可以看到routing参数为{categories} ,可以根据需要保留该参数。 但是,Laravel提供了更改它的选项。

Route::resource('categories', 'CategoriesController', [
    'parameters' => 'singular',
]);
+--------+-----------+------------------------------------+------------------------------------+----------------------------------------------------------------------+-----------------+
| Domain | Method    | URI                                | Name                               | Action                                                               | Middleware      |
+--------+-----------+------------------------------------+------------------------------------+----------------------------------------------------------------------+-----------------+
|        | GET|HEAD  | admin/categories                   | admin.categories.index             | App\Http\Controllers\Admin\CategoriesController@index                | web,admin       |
|        | POST      | admin/categories                   | admin.categories.store             | App\Http\Controllers\Admin\CategoriesController@store                | web,admin       |
|        | GET|HEAD  | admin/categories/create            | admin.categories.create            | App\Http\Controllers\Admin\CategoriesController@create               | web,admin       |
|        | GET|HEAD  | admin/categories/{category}        | admin.categories.show              | App\Http\Controllers\Admin\CategoriesController@show                 | web,admin       |
|        | PUT|PATCH | admin/categories/{category}        | admin.categories.update            | App\Http\Controllers\Admin\CategoriesController@update               | web,admin       |
|        | DELETE    | admin/categories/{category}        | admin.categories.destroy           | App\Http\Controllers\Admin\CategoriesController@destroy              | web,admin       |
|        | GET|HEAD  | admin/categories/{category}/edit   | admin.categories.edit              | App\Http\Controllers\Admin\CategoriesController@edit                 | web,admin       |

Note: Laravel 5.3 uses singular by default.

注意: Laravel 5.3默认使用单数形式。

public function edit(Category $category)
{
    return view('admin.categories.edit', [
        'category'      => $category
    ]);
}

Now, Laravel will automatically resolve the category using the ID parameter, and will throw an exception if the model does not exist.

现在,Laravel将使用ID参数自动解析类别,如果模型不存在,则将引发异常。

Note: To resolve the parameter it uses the findOrFail Eloquent method, unless the parameter has a default value.

注意:要解析该参数,它使用findOrFail方法,除非该参数具有默认值。

Everything looks great for the moment, because we removed the check for the model from all methods. Nevertheless, we still need to catch the exception and take the proper action.

目前,一切看起来都很不错,因为我们从所有方法中删除了对模型的检查。 尽管如此,我们仍然需要捕获异常并采取适当的措施。

处理异常 (Handling Exceptions)

The App\Exceptions\Handler@render method is responsible for converting exceptions to an HTTP response. We’ll be using it to handle the ModelNotFoundException and redirect to the 404 not found page.

App\Exceptions\Handler@render方法负责将异常转换为HTTP响应。 我们将使用它来处理ModelNotFoundException并重定向到404 not found页面。

The render method has a request and exception parameter that we can use to determine what to do.

render方法具有一个request和exception参数,我们可以使用该参数来确定要执行的操作。

public function render($request, Exception $e)
{
    if ($e instanceof ModelNotFoundException) {
        $view = view("admin.404");

        if ($e->getModel() == Category::class) {
            $view->withErrors(['Category not found'])->render();
        }

        return response($view, 404);
    } else {
        // handle other exceptions
        return parent::render($request, $e);
    }
}

We test to see if the thrown exception is an instance of ModelNotFoundException. We can also test the model name to display the proper error message. To avoid adding multiple if tests for all our models we can create an indexed array of messages and use the model class name to pull the proper message.

我们测试一下是否抛出异常是ModelNotFoundException的实例。 我们还可以测试型号名称以显示正确的错误消息。 为了避免为我们所有的模型添加多个if测试,我们可以创建消息的索引数组,并使用模型类名称提取适当的消息。

解析参数 (Resolving Parameters)

Laravel resolves the routing parameters using the name and type hinting. If the parameter type is a model, it tries to find a record in the database using the ID and it fails if no records are found.

Laravel使用名称和类型提示来解析路由参数。 如果参数类型是模型,它将尝试使用ID在数据库中查找记录,如果找不到记录,它将失败。

As a good practice, we tend to avoid exposing our internal IDs to the end user, and this problem is often solved by using universally unique identifiers (UUID). But since Laravel is using the table primary key to resolve the bound parameter, it will always throw an error!

作为一种好习惯,我们倾向于避免将内部ID暴露给最终用户,并且通常通过使用通用唯一标识符(UUID)解决此问题。 但是由于Laravel使用表主键来解析绑定参数,所以它将始终抛出错误!

To solve this problem, Laravel lets us override the getRouteKeyName method from the parent model class. The method should return the attribute name, in this case uuid.

为了解决这个问题,Laravel让我们从父模型类重写getRouteKeyName方法。 该方法应返回属性名称,在这种情况下为uuid

class Category extends Model
{
    // ...

    public function getRouteKeyName()
    {
        return "uuid";
    }
}

Now, if we try editing a specific category using the UUID it should work as expected, e.g. http://local.dev/admin/categories/b86266d4-63c7-11e6-8c98-08002751e440/edit.

现在,如果我们尝试使用UUID编辑特定类别,则它应该可以按预期工作,例如http://local.dev/admin/categories/b86266d4-63c7-11e6-8c98-08002751e440/edit

Got more Laravel tips? Share some with us!

有更多Laravel提示吗? 与我们分享一些!

翻译自: https://www.sitepoint.com/laravel-quick-tip-model-route-binding/

laravel 绑定 区别

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值