Laravel Route 模型绑定与关系
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26888736/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel Route model binding with relationship
提问by Keet
I am wondering if it is possible to return a relationship with laravels Route model binding ?
我想知道是否可以返回与 laravel 路由模型绑定的关系?
Say is a have a user model with a relationship 'friends' to other users, and I want to return both the user info and the relationship from a route or controller.
假设有一个用户模型与其他用户的“朋友”关系,我想从路由或控制器返回用户信息和关系。
eg for the route domain.tld/user/123
例如对于路线 domain.tld/user/123
Route::model('user', 'User');
Route::get('/user/{user}', function(User $user) {
return Response::json($user);
});
this will return me the user info fine but I also want the relationships, is there any easy/proper way to do this ?
这将返回给我的用户信息很好,但我也想要关系,有没有简单/正确的方法来做到这一点?
I know I can do this
我知道我可以做到这一点
Route::get('/user/{user}', function((User $user) {
return Response::json(User::find($user['id'])->with('friends')->get());
});
or
或者
Route::get('/user/{id}', function(($id) {
return Response::json(User::find($id)->with('friends')->get());
});
but I suspect there may be a better way.
但我怀疑可能有更好的方法。
回答by Martin Bean
You don't want to eager-load relationships on everyquery like Matt Burrowsuggests, just to have it available in one context. This is inefficient.
您不想像Matt Burrow建议的那样在每个查询上预先加载关系,只是为了让它在一个上下文中可用。这是低效的。
Instead, in your controller action, you can load relationships “on demand” when you need them. So if you use route–model binding to provide a User
instance to your controller action, but you also want the friends
relationship, you can do this:
相反,在您的控制器操作中,您可以在需要时“按需”加载关系。因此,如果您使用路由模型绑定为User
您的控制器操作提供一个实例,但您也想要这种friends
关系,您可以这样做:
class UserController extends Controller
{
public function show(User $user)
{
$user->load('friends');
return view('user.show', compact('user'));
}
}
回答by Matt Burrow
You can populate the $with
property in the User model. Like so;
您可以$with
在 User 模型中填充该属性。像这样;
protected $with = ['friends'];
This will autoload the relationship data for you automatically.
这将自动为您自动加载关系数据。
Please Note:This will do it for every user model query.
请注意:这将对每个用户模型查询执行此操作。
If you dont want friends to be loaded all the time, then you can bind it to the parameter within your route, like so;
如果你不想一直加载好友,那么你可以将它绑定到你的路由内的参数,像这样;
Route::bind('user_id', function($id) {
return User::with('friends')->findOrFail($id);
});
Route::get('/user/{user_id}', 'BlogController@viewPost');
回答by jsfrank
Martin Bean's response is probably not the way you want to tackle this, only because it introduces an n+1 to your Controller:
Martin Bean 的回应可能不是您想要解决的方式,只是因为它向您的 Controller 引入了 n+1:
1) It must load the User
via Route Model Binding, then....
1)它必须加载User
via Route Model Binding,然后......
2) It now loads the relationship for friends
2)它现在加载关系 friends
He is correct, however, that you probably don't want to load the relationship every time.
但是,他是对的,您可能不想每次都加载关系。
This is why Matt Burrow's solution is probably better (he's binding a different value: instead of {user}
, you could use something like {user_with_friends}
and bind that separately from {user}
...
这就是为什么 Matt Burrow 的解决方案可能更好的原因(他绑定了不同的值:而不是{user}
,您可以使用类似的东西{user_with_friends}
并将其与{user}
...
Personally, I think if you need to load friends
for only that route, I'd simply just pass $userId (without binding), and just begin the controller method with:
就个人而言,我认为如果您只需要friends
为该路由加载,我只需传递 $userId(不绑定),然后以以下方式开始控制器方法:
$user = User::with('friends')->findOrFail($userId);
$user = User::with('friends')->findOrFail($userId);
You can either let Laravel handle the ModelNotFoundException automatically (like it does with Route Model Binding), or wrap it in a try/catch
您可以让 Laravel 自动处理 ModelNotFoundException(就像它使用路由模型绑定一样),或者将它包装在 try/catch 中