在 Laravel 5 中急切加载时约束不生效

Sit*_*ira 1 php laravel eloquent laravel-5 laravel-5.1

我有这个功能来获得加入关系的结果。但是,这些限制似乎并未生效。如果我注释掉约束,它仍然给出与未注释约束相同的结果集。

public function singleCategory($type, $category)
{
    $track = TrackType::with(['tracks.subgenres'], function($query, $category) {
        $query->where('name','=', $category);
    })->where('name', '=', $type)->get();

    dd($track->toArray());
}
Run Code Online (Sandbox Code Playgroud)

任何帮助将非常感激 :)

pat*_*cus 5

约束闭包只传递一个参数:$query。您尝试访问的另一个参数 ( $category) 需要通过use关键字提供:

public function singleCategory($type, $category)
{
    $track = TrackType::with(['tracks.subgenres'], function($query) use ($category) {
        $query->where('name', '=', $category);
    })->where('name', '=', $type)->get();

    dd($track->toArray());
}
Run Code Online (Sandbox Code Playgroud)

编辑

以上不会影响返回的TrackTypes,它只会限制预先加载的相关子流派。根据评论,您似乎试图将返回的 TrackType 限制为包含某个子类型的那些。在这种情况下,您需要使用以下whereHas方法:

public function singleCategory($type, $category)
{
    $track = TrackType::with('tracks.subgenres')
        ->whereHas('tracks.subgenres', function($query) use ($category) {
            $query->where('name', '=', $category);
        })
        ->where('name', '=', $type)
        ->get();

    dd($track->toArray());
}
Run Code Online (Sandbox Code Playgroud)

编辑 2

听起来您的目标结果集实际上是轨道,而不是轨道类型。如果是这样,您可能希望从查询曲目开始,并从那里添加您的过滤条件(我不知道您的确切模型和关系名称,因此进行相应调整):

public function singleCategory($type, $category)
{
    $track = Track::with(['tracktype', 'subgenres'])
        ->whereHas('tracktype', function($query) use ($type) {
            $query->where('name', '=', $type);
        })
        ->whereHas('subgenres', function($query) use ($category) {
            $query->where('name', '=', $category);
        })
        ->get();

    dd($track->toArray());
}
Run Code Online (Sandbox Code Playgroud)

如果您真的想从 TrackType 开始,那么除了添加whereHas()来查找 TrackType 之外,您还需要添加whereHas()来过滤急切加载的轨道:

public function singleCategory($type, $category)
{
    $track = TrackType::with(['tracks' => function ($query) use ($category) {
            $query->whereHas('subgenres', function($query) use ($category) {
                $query->where('name', '=', $category);
            });
        }, 'tracks.subgenres'])
        ->whereHas('tracks.subgenres', function($query) use ($category) {
            $query->where('name', '=', $category);
        })
        ->where('name', '=', $type)
        ->get();

    dd($track->toArray());
}
Run Code Online (Sandbox Code Playgroud)

第一个例子要简洁得多。在简单的英语中,第一个示例听起来像是“获取一种类型和一种子类型的所有曲目”。第二个示例听起来像是“获取曲目类型,但前提是它具有某个子类型中的曲目;此外,仅加载该子类型中的那些曲目”。