php 与关系绑定的Laravel路径模型

2g32fytz  于 2023-01-16  发布在  PHP
关注(0)|答案(3)|浏览(136)

我想知道是否有可能返回一个与laravels 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());

});

但我想可能有更好的办法。

bvhaajcl

bvhaajcl1#

您不希望像Matt Burrow建议的那样,在 * 每个 * 查询上急切地加载关系,只是为了在一个上下文中可用,这是低效的。
相反,在控制器动作中,您可以在需要时“按需”加载关系。因此,如果您使用路由模型绑定为控制器动作提供User示例,但您还需要friends关系,则可以执行以下操作:

class UserController extends Controller
{
    public function show(User $user)
    {
        $user->load('friends');

        return view('user.show', compact('user'));
    }
}

编辑:您也可以使用loadMissing有条件地加载关系。这将仅在关系尚未加载到模型上时加载关系:

class UserController extends Controller
{
    public function show(User $user)
    {
        // If friends relation has already been loaded, will be a no-op
        $user->loadMissing('friends');

        return view('user.show', compact('user'));
    }
}
sczxawaw

sczxawaw2#

您可以在User模型中填充$with属性。

protected $with = ['friends'];

这将自动加载关系数据。

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

如果你不想朋友总是被加载,那么你可以把它绑定到你的路由中的参数,就像这样;

Route::bind('user_id', function($id) {
    return User::with('friends')->findOrFail($id);
});

Route::get('/user/{user_id}', 'BlogController@viewPost');
vsikbqxv

vsikbqxv3#

Martin Bean的回答可能不是您想要的解决方法,这仅仅是因为它向控制器引入了一个n+1:
1)必须通过路由模型绑定加载User,然后...
2)它现在加载friends的关系
然而,他说得对,你可能不想每次都加载关系。
这就是为什么马特·伯罗的解决方案可能更好(他绑定了一个不同的值:您可以使用类似{user_with_friends}的代码来代替{user},并将其与{user}分开绑定...
我个人认为,如果您只需要为该路由加载friends,我只需传递$userId(不绑定),并以如下代码开始控制器方法:
$user = User::with('friends')->findOrFail($userId);
您可以让Laravel自动处理ModelNotFoundException(就像路由模型绑定一样),或者将其 Package 在try/catch中

相关问题