Laravel Route模型绑定关系

时间:2014-11-12 13:58:37

标签: php laravel laravel-routing

我想知道是否可以通过laravels路由模型绑定返回关系?

Say是一个拥有与其他用户“朋友”关系的用户模型,我想从路由或控制器返回用户信息和关系。

例如路线domain.tld/user/123

Route::model('user', 'User');

Route::get('/user/{user}', function(User $user) {

    return Response::json($user);

});

这将返回用户信息,但我也想要关系,有没有简单/正确的方法来做到这一点?

我知道我可以做到这一点

Route::get('/user/{user}', function((User $user) {

    return Response::json(User::find($user['id'])->with('friends')->get());

});

Route::get('/user/{id}', function(($id) {

   return Response::json(User::find($id)->with('friends')->get());

});

但我怀疑可能有更好的方法。

3 个答案:

答案 0 :(得分:13)

您不希望在每个查询上急切加载关系,例如Matt Burrow建议,只是为了让它在一个上下文中可用。这是低效的。

相反,在您的控制器操作中,您可以在需要时“按需”加载关系。因此,如果您使用路由模型绑定为控制器操作提供User实例,但您还需要friends关系,则可以执行以下操作:

class UserController extends Controller
{
    public function show(User $user)
    {
        $user->load('friends');

        return view('user.show', compact('user'));
    }
}

答案 1 :(得分:12)

您可以在User模型中填充$with属性。像这样;

protected $with = ['friends'];

这将自动为您自动加载关系数据。

请注意:这将针对每个用户模型查询执行此操作。

如果您不想一直加载朋友,那么您可以将其绑定到路线中的参数,就像这样;

Route::bind('user_id', function($id) {
    return User::with('friends')->findOrFail($id);
});

Route::get('/user/{user_id}', 'BlogController@viewPost');

答案 2 :(得分:0)

马丁·宾恩(Martin Bean)的响应可能不是您要解决此问题的方式,仅是因为它为控制器引入了n + 1:

1)它必须通过路由模型绑定来加载User,然后....

2)现在,它加载了friends

的关系

但是,他是正确的,您可能不想每次都加载该关系。

这就是为什么马特·伯罗(Matt Burrow)的解决方案可能更好的原因(他绑定了一个不同的值:可以使用{user}之类的东西代替{user_with_friends}并将其与{user}分开绑定...

我个人认为,如果您只需要为该路由加载friends,我只需传递$ userId(无绑定),然后以以下方式开始控制器方法:

$user = User::with('friends')->findOrFail($userId);

您可以让Laravel自动处理ModelNotFoundException(就像使用Route Model Binding一样),也可以将其包装在try / catch中