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:在自定义 Route::model 绑定中使用模拟实例