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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 10:25:21  来源:igfitidea点击:

Laravel Route model binding with relationship

phplaravellaravel-routing

提问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 Userinstance to your controller action, but you also want the friendsrelationship, 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 $withproperty 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 Uservia Route Model Binding, then....

1)它必须加载Uservia 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 friendsfor 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 中