开发者社区 问答 正文

Laravel雄辩地说,联接表并进行过滤查询

我正在尝试编写查询以过滤表,但是看起来有些不对劲。

    $city = $request->get("city");
    $price = $request->get("price");

首先检查计划表是否为空。然后开始编写过滤查询。

    ->groupBy("address","place_name")
    ->when($keyword, function($query, $keyword) {
        return $query->where("place_name", "LIKE", "%$keyword%");
    })
    ->when($city, function($query, $city) {
        return $query->where("city", "LIKE", "%$city%");
    })

查询工作到basic_info表。但是当我$keyword在basic_info表中搜索时会弹出错误提示 调用模型> [App \ Model \ Place]上未定义的关系[basic_infos]。

    ->when($keyword, function($query) use ($keyword){
        $query->with(["basic_infos" => function($query, $keyword){
            return $query->where("basic_info.wedding_style", "LIKE", "%$keyword%");
        }]);
    })
    //plan table
    ->when($price, function($query) use ($price){
        $query->with(["basic_infos" => function($query, $price){
            return $query->where("plans.plan_price", "<=", $price);
        }]);
    })

    ->paginate(20);
    return $datas;

但是实际上它是定义的。这是模特

放置模型

{
    return $this->hasMany("App\Model\BasicInfo");
}

基本信息模型

{
    return $this->belongsTo("App\Model\Place");
}

但是在->when函数内部的查询中,当我使用->with它时,似乎发生了问题。我想,我在错误的时间使用了它,否则…… plan表的查询肯定也会发生同样的事情。正确的方法是什么?

展开
收起
社区秘书 2019-11-29 11:31:48 615 分享 版权
阿里云 AI 助理回答

从你的描述来看,问题出在你尝试使用with进行关联查询时的上下文和语法。with用于预加载(eager loading)关联模型,而你在when条件闭包中使用它的方式似乎有些混淆了关联关系的调用以及如何正确传递变量到闭包中。

首先,确保你理解了Eloquent ORM中关联关系的定义:在Place模型中定义的hasMany("App\Model\BasicInfo")表明一个Place可以有多个BasicInfo,而在BasicInfo模型中的belongsTo("App\Model\Place")则表示一个BasicInfo属于一个Place

针对你的代码,这里有一个修正建议:

  1. 直接在主查询上应用过滤条件:如果你想要基于$keyword$city$price来过滤结果,并且这些条件可能涉及到了关联表basic_info和当前操作的表(假设是Plan),那么应该直接在查询链中加入这些条件,而不是通过with预加载的方式去实现过滤逻辑。

  2. 处理关联查询:当你确实需要预加载关联数据以减少查询次数时,应确保正确地构建关联查询,但过滤逻辑通常不在这个环节处理。

  3. 修正示例代码:根据你的需求,看起来你想根据关键词搜索place_namewedding_style,同时根据城市和价格筛选。下面是一个更清晰的示例,假设你正在处理的是Plan模型,且计划与地点(Place)有关联,地点又与基本信息(BasicInfo)有关联:

$datas = Plan::query();

// 城市过滤
if ($city) {
    $datas->whereHas('place', function ($query) use ($city) {
        $query->where('city', 'LIKE', "%$city%");
    });
}

// 价格过滤
if ($price) {
    $datas->where('plan_price', $price); // 或者使用范围查询如 whereBetween 如果你需要价格区间
}

// 关键词搜索,同时在两个表中查找
if ($keyword) {
    $datas->where(function ($query) use ($keyword) {
        $query->where('place_name', 'LIKE', "%$keyword%")
              ->orWhereHas('place.basicInfos', function ($query) use ($keyword) {
                  $query->where('wedding_style', 'LIKE', "%$keyword%");
              });
    });
}

// 分页
$datas = $datas->with(['place' => function ($query) {
    // 如果需要预加载关联的地方,可以在这里添加,例如加载所有关联的基本信息
    $query->with('basicInfos');
}])->paginate(20);

return $datas;

这段代码首先构建了一个对Plan模型的查询,然后根据条件逐步添加了过滤逻辑。注意,我使用了whereHas来过滤与Place关联的数据,这允许你基于关联表的字段进行过滤。对于关键词搜索,我同时在Plan表的place_name字段和通过关联的BasicInfo模型的wedding_style字段中进行了模糊匹配。

请根据你的实际数据库结构和模型关系调整上述代码。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答
问答分类:
PHP
问答地址: