-1

有没有一种干净的方法可以WHERE ... IN ()使用 Eloquent/laravel 进行复合条件。

查询结果将是:

SELECT * FROM `table` WHERE (relation_type, relation_id) IN (('App\\Model', 1),('App\\Model', 3))

如您所见,这对于对具有链接到其他 5 个模型的多态关系的实体的单个查询获取很有帮助。

我目前的解决方案是纯粹的MySQL

//Example :array of array with Model name & id
$couples = [
    ['relation_type' => 'App\\Model', 'relation_id' => 1],
    ['relation_type' => 'App\\ModelTwo', 'relation_id' => 2],
    ['relation_type' => 'App\\ModelThree', 'relation_id' => 5],
    ['relation_type' => 'App\\ModelTwo', 'relation_id' => 20],
    //...
    ['relation_type' => 'App\\Model', 'relation_id' => 999],
];
$query = "SELECT * FROM table WHERE ('relation_type', 'relation_id') IN (("
        .implode('),(', array_map(function ($entry) {
            return "'".$entry['relation_type']."',".$entry['relation_id']; //I know , in relation_type the '\' needs to be escaped. 
        }, $couples))
        ."))";
$results = \DB::select($query);
}
4

1 回答 1

3

首先,您可以DB::raw同时输入列和值,这将解决使 SQL 查询正确的问题,我测试了以下内容MySql 5.7并且它可以工作。Db::raw 只是将原始字符串添加到查询中,注入可能很危险。

->whereIn(DB::raw('(relation_type, relation_id)'), [DB::raw("('App\\Model', '2')")])

现在我们只需要将您的数组转换为该结构,我的方法是 array_mapforeach也可以做到这一点。

$couples = array_map(function ($item) {
    $type = $item['relation_type'];
    $id = $item['relation_id'];

    return DB::raw("('$type', '$id')");
}, $couples);

然后用一个简单的Laravel查询调用它,你应该很高兴。

$models = Model::whereIn(DB::raw('(relation_type, relation_id)'), $couples)->get()
于 2019-09-06T19:14:58.200 回答