【问题标题】:Laravel Route model binding with relationshipLaravel Route 模型与关系绑定
【发布时间】:2015-01-09 09:49:21
【问题描述】:

我想知道是否可以返回与 laravel Route 模型绑定的关系?

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

例如路线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());

});

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

【问题讨论】:

    标签: php laravel laravel-routing


    【解决方案1】:

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

    1) 必须通过Route Model Binding加载User,然后....

    2) 现在加载friends的关系

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

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

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

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

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

    【讨论】:

    • Martin Bean 的响应可能不是您想要解决这个问题的方式,只是因为它向您的控制器引入了一个 n+1。不,它没有。
    【解决方案2】:

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

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

    class UserController extends Controller
    {
        public function show(User $user)
        {
            $user->load('friends');
    
            return view('user.show', compact('user'));
        }
    }
    

    【讨论】:

    • 谢谢。您也可以使用load,有点像with,例如作为更复杂查询的一部分,例如:return $module->load(['questions', 'questions.results' => function($q) use($user){ return $q->where('user_id', $user->id); }]);
    • @Djave load() 用于在执行查询之后加载关系,with() 用于将关系作为查询的一部分。
    • 根据问题,当然 protected $with 值得回答,但总的来说,根据应用程序性能,这是我们应该遵循的。只需在需要时显式加载即可。
    【解决方案3】:

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

    protected $with = ['friends'];
    

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

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

    如果你不希望好友一直被加载,那么你可以将它绑定到你的路由中的参数,像这样;

    Route::bind('user_id', function($id) {
        return User::with('friends')->findOrFail($id);
    });
    
    Route::get('/user/{user_id}', 'BlogController@viewPost');
    

    【讨论】:

    • 谢谢男人 protected $with = ['friends'];救了我的命(:
    猜你喜欢
    • 2018-01-10
    • 2015-07-12
    • 2015-05-23
    • 1970-01-01
    • 2021-07-04
    • 1970-01-01
    • 1970-01-01
    • 2014-12-31
    • 2021-08-29
    相关资源
    最近更新 更多