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

时间:2018-01-24 15:06:05

标签: laravel api routes postman

所有!!

我试图在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);
}

以下是我创建的相同逻辑show方法使用id来获取我的产品并且它工作正常,但是当我创建一个名为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);
}

获取"抱歉,找不到您要查找的页面" 我不知道发生了什么事,所以如果有人能帮助我,我会非常感激。

提前致谢!!

3 个答案:

答案 0 :(得分: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');

答案 1 :(得分:0)

{id}路线中的Route::get('product/{id}', 'ProductController@show');匹配的内容没有限制。

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

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

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

正如您将看到所有使用EAN的网址现在都可以使用,但ID会停止工作。

为防止“与此路线匹配的所有变量”行为,您可以限制ID或条形码的范围,因为条形码具有您最容易使用的限制。

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

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

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

答案 2 :(得分:0)

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

  

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);
}

它有效!

非常感谢你的帮助!!