首页 > 解决方案 > 雄辩的“何时”方法又一个“何时”

问题描述

我为此搜索了很多,但找不到相关问题。

我的应用程序中有一个 Eloquent 查询,如下所示:

$cidades = Cidade::when($pesquisa, function ($q) use ($pesquisa) {
    return $q->where('nome', 'like', '%' . $pesquisa . '%')
        ->orWhere('iso_ddd', 'like', '%' . $pesquisa . '%');
})
    ->when($estado, function ($q) use ($estado) {
        return $q->where('estado_id', $estado);
    })
    ->sortable('nome')
    ->simplePaginate($request->input('p'));

如您所见,我有两种“何时”过滤内容的方法。我的目的是检查它们是否处于活动状态并相应地过滤查询。但是上面的查询只有在其中只有一个同时处于活动状态时才有效。如果设置了 $pesquisa,则它使用该函数过滤内容,但忽略后面的“何时”(任何 $estado 的对象都会出现)。如果没有设置 $pesquisa 而设置了 $estado,那么它只会正确运行 $estado 的“何时”。

我可以通过在 $pesquisa 的 'when' 中复制 $estado 的 'when' 来使其按预期运行,如下所示:

$cidades = Cidade::when($pesquisa, function ($q) use ($pesquisa, $estado) {
    return $q->where('nome', 'like', '%' . $pesquisa . '%')
        ->when($estado, function ($q) use ($estado) {
            return $q->where('estado_id', $estado);
        })
        ->orWhere('iso_ddd', 'like', '%' . $pesquisa . '%');
})
    ->when($estado, function ($q) use ($estado) {
        return $q->where('estado_id', $estado);
    })
    ->sortable('nome')
    ->simplePaginate($request->input('p')); 

但我觉得有点多余。有没有其他方法可以查询?

标签: laraveleloquent

解决方案


or我怀疑这个问题是有牵连的事实。当两者都设置时,这是你得到的:

SELECT * FROM cidades WHERE nom LIKE ? OR iso_ddd LIKE ? AND estado_id = ?

由于AND具有更高的关联性,OR这将获得所有记录,nom LIKE ? OR (iso_ddd LIKE ? AND estado_id = ?)而这并不完全是您想要的。

你可以试试:

$cidades = Cidade::when($pesquisa, function ($q) use ($pesquisa) {
    return $q->where(function ($q) use ($pesquisa) {
          $q->where('nome', 'like', '%' . $pesquisa . '%')
           ->orWhere('iso_ddd', 'like', '%' . $pesquisa . '%');
       });
    })->when($estado, function ($q) use ($estado) {
        return $q->where('estado_id', $estado);
    })
    ->sortable('nome')
    ->simplePaginate($request->input('p'));

这应该用括号括起来(nom = ? or iso_ddd = ?)以确保正确分组条件。


推荐阅读