Laravel 5.5 资源自定义 show($id) 方法

Posted

技术标签:

【中文标题】Laravel 5.5 资源自定义 show($id) 方法【英文标题】:Laravel 5.5 Resources Customize show($id) method 【发布时间】:2018-07-03 16:25:46 【问题描述】:

全部!!

我正在尝试在 Laravel 5.5 中开发一个 API,我真的坚持这一点:

我有这条路线:

Route::get('products', 'ProductController@index'); ==> Works OK
Route::get('product/id', 'ProductController@show'); ==> Works OK
Route::get('product/barcode', 'ProductController@productByEan'); ==> Fail

使用这些方法:

public function index()

  $product = Product::paginate(15);
  return ProductResource::collection($product);


public function show($id)

  $product = Product::findOrFail($id);
  return new ProductResource($product);

以下是相同的逻辑,我使用 id 创建了 show 方法来获取我的产品,它工作正常,但是当我创建一个名为 productByEan 的新方法来使用 EAN13(条形码)而不是使用此方法的 id 获取产品时 (使用带有此 URL 的邮递员:http://ws.barcode.primerbit.com/api/product/9440396613933):

public function productByEan($barcode)
   
    $response =  Product::where('barcode',$barcode);
    return new ProductResource($response);

获取“抱歉,找不到您要查找的页面” 我不知道发生了什么,所以如果有人可以帮助我,我将非常感谢。

提前致谢!!

【问题讨论】:

非常感谢!!我会尽一切努力,看看会发生什么,但我忽略的一个小细节是产品 id 它' pk 但条形码是同一张表上的另一个字段。我可以使用带有非 pk 字段的 show 方法吗? 【参考方案1】:

由于你已经有了product/id 路由,product/barcode 将永远不会被执行。因此,将其更改为:

product/barcode/barcode

或者你可以使用不同的动词,比如 POST 而不是 GET 这条路线:

Route::post('product/barcode', 'ProductController@productByEan');

您也可以尝试更改这两条路线的顺序并添加regular expression constraint:

Route::get('product/barcode', 'ProductController@productByEan')->where('barcode', '[0-9]13');    
Route::get('product/id', 'ProductController@show');

【讨论】:

【参考方案2】:

Route::get('product/id', 'ProductController@show'); 路由中匹配您的id 没有限制。

这意味着任何匹配product/* 的东西都将使用ProductController@show 方法。

您可以通过切换 2 条路线亲自尝试。即

Route::get('product/barcode', 'ProductController@productByEan');
Route::get('product/id', 'ProductController@show');

您将看到所有使用 EAN 的 url 现在都可以使用,但 id 将停止工作。

为了防止“所有变量匹配此路径”行为,您可以限制 ID 或条形码的范围,因为条形码具有现成的限制,您可以最轻松地使用它。

尝试切换路线并将条形码路线更改为:

Route::get('product/barcode', 'ProductController@productByEan')->where('barcode', '[0-9]13');

这将确保条形码必须匹配一个 13 位长的数字。任何其他数字或字符串都不会匹配,因此会根据 ID 传递到您的其他路由。

【讨论】:

【参考方案3】:

最后我找到了这个问题的解决方案,错误不在规则中,实际上我没有更改任何规则,问题是我在 ProductController 中的 productByEan() 方法,因为该方法引用了 ProductResource ,所以当我尝试创建 ProductResource 的新实例时,雄辩无法获取对象属性并引发以下异常:

ErrorException (E_NOTICE) 未定义属性:Illuminate\Database\Eloquent\Builder::$id

其中 $id 是 ProductResource 中的第一个属性:

 public function toArray($request)

   // return parent::toArray($request);

   return [
        'id' => $this->id,
        'barcode' => $this->barcode,
        'description' => $this->description,
        'price' => $this->price,
        'currency'=> $this->currency

   ];

`

因此,解决方案是从此更改 ProductByEan 方法:

 public function productByEan($barcode)
   
    $response =  Product::where('barcode',$barcode)->get();

     return  new ProductResource::collection($response);

到这里:

 public function productByEan($barcode)
   
    $response =  Product::where('barcode',$barcode)->get();

     return  ProductResource::collection($response);

而且它有效!

非常感谢您的帮助!!

【讨论】:

以上是关于Laravel 5.5 资源自定义 show($id) 方法的主要内容,如果未能解决你的问题,请参考以下文章

Gradle插件开发 APK瘦身资源自定义7z压缩

android学习笔记40——国际化和资源自适应

如何将 laravel 日志文件数据存储到数据库中(5.5)[关闭]

Laravel 5.5 ReferenceError:$ 未定义

Laravel 5.5 的自定义验证对象/类

Laravel 5.5 / 验证器 / 自定义规则