尽管有“ where”语句,Laravel Query Builder仍返回所有行

时间:2019-04-11 11:40:33

标签: php laravel eloquent

我正在使用以下博客文章提供搜索服务:https://m.dotdev.co/writing-advanced-eloquent-search-query-filters-de8b6c2598db

除我的查询返回表中的每一行而不是特定行之外,这似乎奏效。

例如,我有一个这样的过滤器:

 public static function apply(Builder $builder, $value)
    {
        return $builder->whereHas('items', function ($q) use ($value) {
            $q->where('item_id', $value);
        });
    }

这适用于我的模型上的items关系。按照惯例,运行此查询似乎可以正常运行,但相对于上述博客文章中的代码而言,它失败。

对于更简单的查询也是如此:

public static function apply(Builder $builder, $value)
    {
        return $builder->where('name', $value);
    }

运行测试时,它只会给我表中的每个项目,而不是满足我条件的项目。

我的搜索代码如下所示,但看不到任何明显的错误:

 public static function search(Request $filters)
    {
        $query =
            static::applyDecoratorsFromRequest(
                $filters,
                (new User)->newQuery()
            );

        return static::getResults($query);
    }

    private static function applyDecoratorsFromRequest(Request $request, Builder $query)
    {
        foreach ($request->all() as $filterName => $value) {

            $decorator = static::createFilterDecorator($filterName);

            if (static::isValidDecorator($decorator)) {
                $query = $decorator::apply($query, $value);
            }
        }
        return $query;
    }

任何帮助表示赞赏!

1 个答案:

答案 0 :(得分:1)

这是因为您应该使用本地范围:https://laravel.com/docs/5.8/eloquent#local-scopes

public static function scopeWhereItem(Builder $query, $value)
    {
        return $query->whereHas('items', function (query) use ($value) {
            $query->where('item_id', $value);
        });
    }

然后在您的控制器中:


// Initiate the queryBuilder
$query = YourModel::query();

// your request is like : ['item' => '2'];

foreach($request->all()sas $filterName => $value) {

    // Build the scope Name (whereItem())
    $scope_name = 'where' . ucFirst($filterName);

    $query->$scopeName($value);

}

$results = $query->get();

如果需要,您可以添加一些检查,以确定方法'scope' . ucFirst($scopeName)是否存在

它将生成如下查询:YourModel::query()->whereItem(2)->get()'