【问题标题】:Laravel resource routes with id's in the URL and model association在 URL 和模型关联中带有 id 的 Laravel 资源路由
【发布时间】:2021-02-13 15:44:00
【问题描述】:

我有一个 laravel 应用程序,其中包含一堆具有 LIST、VIEW、EDIT、CREATE 和 DELETE 的 CRUDS。这一切都很好。我想到的问题是,其中一个 CRUDS 将根据用户拥有的公司 ID 进行过滤。设置是 1 个用户可以拥有许多公司,每个公司可以有许多优惠。因此,offer CRUD 需要根据公司 id 进行过滤。

在我更改之前,路线是这样的

Route::resource('offers', 'OfferController');

因此 ressource 路由负责生成不同的 URL

  • 报价(列表)
  • 优惠/10(显示)
  • offer/10/edit(编辑)
  • 提供/创建(创建)
  • offer/10/update(保存编辑)
  • offer/10/store(保存创建)
  • offer/10/delete(销毁offer)

资源似乎神奇地将商品 ID 与模型相关联,即使路径中未指定 ID。这太棒了。但是一旦你在 URL 中添加一个新的 var,它就不再起作用了。

我的路线现在看起来像这样

Route::resource('{merch}/offers', 'OfferController');

由于涉及第二个 ID,报价模型不能再“自动关联”

在资源中添加 {merch} 后,我最终得到一个如下所示的 URL:

  • 25/报价(列表)
  • 25/offer/10(演出)
  • 25/offer/10/edit(编辑)
  • 25/offer/create(创建)
  • 25/offer/10/update(保存编辑)
  • 25/offer/10/store(保存创建)
  • 25/offer/10/delete(销毁offer)

其中 25 是公司 ID,10 是报价 ID

在 URL 中添加 {merch} 变量之前的控制器如下所示

public function show(Offer $offer)
{
    abort_if(Gate::denies('offer_show'), Response::HTTP_FORBIDDEN, '403 Forbidden');

    $offer->load('categories', 'tags');

    return view('admin.offers.show', compact('offer'));
}

所以我把它改成了:

public function show($merch, Offer $offer)
{
    abort_if(Gate::denies('offer_show'), Response::HTTP_FORBIDDEN, '403 Forbidden');

    $offer->load('categories', 'tags');

    return view('admin.offers.show', compact('offer', 'merch'));
}

我遇到的问题是 $offer 现在似乎未定义。它似乎不再找到实际的报价 ID,并且似乎无法关联任何东西。我得到的关于类别的错误不是集合 $offer 的实例。

请注意,在添加 {merch} 之前,一切正常。当 URL 有 2 个 id 时,我如何从 Laravel“魔术”关联中受益?

当我看到 Offer $offer 不再相关时,我想我可能需要用更具体的东西替换路线。所以我做了这样的事情:

// Offers
Route::get('{merch}/offers', 'OfferController@index');
Route::get('{merch}/offers/create', 'OfferController@create');
Route::post('{merch}/offers/store', 'OfferController@store');
Route::get('{merch}/offers/{id}/edit', 'OfferController@edit');
Route::put('{merch}/offers/{id}/update', 'OfferController@update');
Route::delete('{merch}/offers/{id}/delete', 'OfferController@destroy');
Route::get('{merch}/offers/{id}', 'OfferController@show');

但是,Offer $offer 与 {id} 无关

【问题讨论】:

  • 似乎你可以定义自定义路由,因为资源路由只是让 GET/POST/PUT/PATCH/DELETE 检查这个laravel.com/docs/8.x/…
  • 我昨天试过了,但这并没有解决控制器标头中的 Offer $offer 似乎仍然没有关联数据的事实。我在路线中有很长的{merch}/offer/{id}行
  • 好的,我找到了如何做到这一点。答案是嵌套资源。 Route::resource('merchants.offers', 'OfferController');明天 24 小时结束后,我将发布一个完整的遮阳篷!

标签: php laravel


【解决方案1】:

好的,所以在阅读 laravel 文档之后,有一种称为嵌套资源的方法可以完全满足我的需要。它是这样的:

由于我要查找的 {merch} 变量是商家 ID,因此有一种方法可以使用资源将它们嵌套在一个调用中,如下所示:

Route::resource('merchants.offers', 'OfferController');

URL 将是

  • merchants/25/offers(列表)
  • merchants/25/offers/10(显示)
  • merchants/25/offers/10/edit(编辑)
  • merchants/25/offers/create(创建)
  • merchants/25/offers/10/update(保存编辑)
  • merchants/25/offers/10/store(保存创建)
  • merchants/25/offers/10/delete(销毁优惠)

控制器将如下所示

public function show(Merchant $merchant, Offer $offer)
{
    abort_if(Gate::denies('offer_show'), Response::HTTP_FORBIDDEN, '403 Forbidden');
    $offer->load('categories', 'tags');
    return view('admin.offers.show', compact('offer', 'merchant'));
}

就这样,一切都已解决并按预期工作!

【讨论】:

    猜你喜欢
    • 2018-01-16
    • 1970-01-01
    • 2014-10-23
    • 2017-09-16
    • 2013-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-10
    相关资源
    最近更新 更多