Laravel Route 模型与关系绑定

Posted

技术标签:

【中文标题】Laravel Route 模型与关系绑定【英文标题】:Laravel Route model binding with relationship 【发布时间】: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());

);

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

【问题讨论】:

【参考方案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'];救了我的命(:

以上是关于Laravel Route 模型与关系绑定的主要内容,如果未能解决你的问题,请参考以下文章

在升级laravel 5.2到5.3之后,无法在Route :: model中绑定模型

Laravel 5.2路径模型使用方法和控制器进行绑定

Blade 视图组件的 Laravel 路由模型绑定

Laravel:在自定义 Route::model 绑定中使用模拟实例

Laravel 模型用户自定义绑定“/users/me/xxx”

Laravel 路由问题:自动重定向到根文件夹