Laravel嵌套路由模型绑定

时间:2015-07-23 08:55:32

标签: php laravel

我正在使用Laravel开发一个用于移动应用程序的API,并且在嵌套路由上遇到一些路由模型绑定问题。 该应用程序将有一个独立的sqlite数据库,当网络可用时,它将同步客户端旅程与中央服务器。因此,应用程序中的PK不能用于访问中央服务器上的记录。每个用户都有一个唯一的用户名,该用户名将存储在中央服务器的表格中,其中包含以下列:

  
      
  • user_id
  •   
  • 用户名
  •   

旅程表将包含以下列:

  
      
  • journey_id
  •   
  • USER_ID
  •   
  • user_journey_id
  •   

其中user_journey_id将是客户端设备上旅程记录的PK。 这个想法是客户可以通过以下方式访问api: http://example.com/api/client/UNIQUE_USERNAME/journey/1234 从中央服务器检索旅程。

我有以下资源设置:

Route::resource('client','ClientController');
Route::resource('client.journey','JourneyController');

并为客户端成功设置路由模型绑定,如下所示:

$router->bind('client', function($value, $route) {
    return \App\Client::where('username', '=', $value)->firstOrFail();
});

我在设置嵌套模型绑定时遇到了一些麻烦,因为我需要将客户端usernameuser_journey_id结合使用来检索正确的旅程。有没有办法用路由模型绑定来做到这一点?
或者这应该在控制器中完成,例如:

public function show(Client $client, $user_journey_id)
{
   ... // have logic here to get the journey.

这就是我目前的做法,但路线模型绑定肯定会让它更容易。

2 个答案:

答案 0 :(得分:2)

在Laravel中,当然可以将多个URL参数绑定到模型,就像嵌套路径模型绑定一样。

需要注意的是,您需要为这些特定路线单独指定路线,而不是像您在示例中使用的那样使用Laravel的资源控制器。

要注册具有多个模型绑定的路由,您需要执行以下操作:

路线定义:

Route::get('/api/client/{user}/journey/{journey}', [
  'as' => 'client.journey', 
  'uses' => 'JourneyController@getJourney'
]);

绑定定义:

$router->bind('user', function($value, $route) {
    return \App\Client::where('username', '=', $value)->firstOrFail();
});

$router->bind('journey', function($value, $route) {
    return \App\Journey::where('user_journey_id', '=', $value)->firstOrFail();
});

然后,您将发现两个模型都已解析并注入控制器类中的action方法:

public function show(User $user, Journey $journey)
{
     //do whatever you need to do here...

这种方法唯一真正的缺点是你必须手动定义路由而不是使用Laravel的便捷资源控制器。当然,您可以实现一些自己的逻辑,以便您更容易定义这些类型的路由。

答案 1 :(得分:0)

我认为您的方法并不好,无论如何都要使用单独的控制器,因为您可能需要在将来添加auth层或更多功能。

拥有用户名是URL不好,因为它可能是一个带有特殊字符的字符串,将被URL编码,然后解码,因此容易出错。我建议使用id作为API。

资源会为每个请求的操作调用一个特定的方法,我建议使用这些方法。