Laravel Route模型绑定关系

Kee*_*eet 12 php laravel laravel-routing

我想知道是否有可能返回与laravels Route模型绑定的关系?

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

例如,路线 domain.tld/user/123

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

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

    return Response::json($user);

});
Run Code Online (Sandbox Code Playgroud)

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

我知道我能做到这一点

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

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

});
Run Code Online (Sandbox Code Playgroud)

要么

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

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

});
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*ean 19

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

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

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

        return view('user.show', compact('user'));
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @Djave`load()`用于加载关系_after_已执行查询,`with()`用于包含关系作为查询的一部分. (5认同)

Mat*_*row 13

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

protected $with = ['friends'];
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

Route::get('/user/{user_id}', 'BlogController@viewPost');
Run Code Online (Sandbox Code Playgroud)


小智 5

Martin Bean 的回应可能不是您想要解决此问题的方式,只是因为它向您的 Controller 引入了 n+1:

1)它必须加载Uservia Route Model Binding,然后......

2)它现在加载关系 friends

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

这就是为什么 Matt Burrow 的解决方案可能更好的原因(他绑定了一个不同的值:而不是{user},您可以使用类似的东西{user_with_friends}并将其与{user}...

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

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

您可以让 Laravel 自动处理 ModelNotFoundException(就像它使用路由模型绑定一样),或者将它包装在 try/catch 中