php - 在 URL 和模型关联中带有 id 的 Laravel 资源路由
问题描述
我有一个带有一堆 CRUDS 的 laravel 应用程序,其中包含 LIST、VIEW、EDIT、CREATE 和 DELETE。这一切都很好。我想到的问题是,其中一个 CRUDS 将根据用户拥有的公司 ID 进行过滤。设置是 1 个用户可以拥有许多公司,每个公司可以有许多报价。因此,offer CRUD 需要根据公司 id 进行过滤。
在我更改之前,路线看起来像这样
Route::resource('offers', 'OfferController');
因此 ressource 路由负责生成不同的 URL
- 报价(列表)
- 报价/10 (显示)
- 报价/10/编辑(编辑)
- 提供/创建(创建)
- offer/10/update(保存编辑)
- offer/10/store(保存创建)
- offer/10/delete(销毁offer)
即使在路由中未指定 ID,资源似乎也神奇地将商品 ID 与模型相关联。这太棒了。但是,一旦您在 URL 中添加新的 var,它就不再起作用了。
我的路线现在看起来像这样
Route::resource('{merch}/offers', 'OfferController');
由于涉及第二个 ID,报价模型不能再“自动关联”
在资源中添加 {merch} 后,我最终得到一个如下所示的 URL:
- 25/报价(列表)
- 25/优惠/10 (显示)
- 25/offer/10/edit(编辑)
- 25/报价/创建(创建)
- 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} 无关
解决方案
好的,所以在阅读了 laravel 文档之后,有一种称为嵌套资源的方法可以完全满足我的需要。它是这样的:
由于我正在寻找的 {merch} 变量是商家 ID,因此有一种方法可以使用资源将它们嵌套在一个调用中,如下所示:
Route::resource('merchants.offers', 'OfferController');
然后 URL 将是
- 商家/25/优惠(列表)
- 商家/25/优惠/10(显示)
- 商家/25/优惠/10/编辑(编辑)
- 商家/25/优惠/创建(创建)
- 商家/25/offers/10/update(保存编辑)
- 商家/25/offers/10/store(保存创建)
- 商家/25/offers/10/delete(销毁offer)
然后控制器看起来像这样
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'));
}
就像这样,一切都得到了解决并按预期工作!
推荐阅读
- java - JAX-RS API 端点返回不带西班牙语字符的文件名
- wordpress - 处理请求元素时发生以下错误:无效文件
- c# - ASP.NET Api 仅更新非空属性
- javascript - 在 Javascript 中渲染一个球体
- javascript - 图像不替换为 jQuery [Elementor]
- stack - 在 hackthebox academy 基于堆栈的缓冲区溢出源中无法使用 shellcode
- node.js - 如何从 Node js 获取 qrcode 的图像 src。反应 js
- python - 将 numpy 数组中的数据读入 pytorch 张量而不创建新张量
- flutter - 我想要一张图片作为背景而不是颜色
- post - 如何使用 feign 客户端发布带有标头和正文的 x-www-form-urlencoded 请求?