首页 > 解决方案 > 将 laravel 请求参数与数组合并

问题描述

我正在尝试使用 eloquent 的查询构建器获取 laravel-scout tntsearch,这已被证明很困难,因此我目前的方法是首先使用 tntsearch 获取结果,从结果中提取 id,然后添加带有提取的 id 的 wherIn 子句,做这我有一个额外的类 QueryFilters 以可组合的方式进行排序和过滤。

问题是我收到以下错误:

Call to undefined method App\Filters\QueryFilters::merge()

这是我的代码:

public function search(Request $request, QueryFilters $filters)
    {
        //Search with tntsearch 
        $posts = Post::search($request->input('search'))->get();

        //Grab ids and prepare to merge with $filters
        $postIds = $posts->pluck('id');
        $toMerge = collect(['whereIn' => $postIds]);

        $filters->merge($toMerge);
        //Filter and sort results
        $posts = Post::filter($filters)->with(['postcategory','author','favorites'])->paginate(10);
}

QueryFilters 的工作原理是遍历请求对象以查找具有相同名称的方法并每次返回查询构建器的实例。

<?php
namespace App\Filters;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;

class QueryFilters
{
    protected $request;
    protected $builder;

    public function __construct(Request $request)
    {
        $this->request = $request;
    }

    public function title($term)
    {
        $lowerCaseTerm = strtolower($term);

        return $this->builder->where('title', 'LIKE', "%$lowerCaseTerm%");
    }

    public function postCategory($term)
    {
        if($term == 0)
        {
            return $this->builder->whereHas('postcategory', function ($query) use ($term){
                $query->where('id', '>', 0);
            });
        }

        return $this->builder->whereHas('postcategory', function ($query) use ($term){
            $query->where('id', $term);
        });
    }

    public function sortBy($term)
    {
        $sortArray = explode(",", $term);

        for($i = 0; $i < count($sortArray); $i++)
        {
            $sortBy = substr_replace($sortArray[$i], "", -1);

            $sortChar = substr($sortArray[$i], -1);

            $sortOrder = $sortChar == '+' ? 'ASC' : 'DESC';  

            $this->builder->orderBy($sortBy, $sortOrder);
        }

        return $this->builder;
    }

    public function whereIn($postIds)
    {
        return $this->builder->whereIn('id', $postIds);
    }

    public function apply(Builder $builder)
    {
        $this->builder = $builder;
        foreach ($this->filters() as $name => $value)
        {
            //if method doesn't exists continue out of the loop 
            if ( ! method_exists($this, $name))
            {
                continue;
            }
            //method exists so check if it has a value payload so call the method with arguments
            if (strlen($value)) 
            {
                $this->$name($value);
            } 
            //it doesn't have a payload so call the method without arguments
            else 
            {
                $this->$name();
            }
        }
        return $this->builder;
    }

    public function filters()
    {
        //returns associative array of request body key value pairs
        return $this->request->all();
    }

}

要了解有关本课程的更多信息,请参阅这篇中篇文章: https ://medium.com/@mykeels/writing-clean-composable-eloquent-filters-edd242c82cc8

如果我 dd $filters 我得到这个:

QueryFilters {#457
  #request: Request {#43
    #json: null
    #convertedFiles: null
    #userResolver: Closure($guard = null) {#421
      class: "Illuminate\Auth\AuthServiceProvider"
      this: AuthServiceProvider {#41 …}
      use: {
        $app: Application {#2 …}
      }
      file: "C:\xampp\htdocs\dog-media.es\vendor\laravel\framework\src\Illuminate\Auth\AuthServiceProvider.php"
      line: "83 to 85"
    }
    #routeResolver: Closure() {#423
      class: "Illuminate\Routing\Router"
      this: Router {#26 …}
      use: {
        $route: Route {#220 …}
      }
      file: "C:\xampp\htdocs\dog-media.es\vendor\laravel\framework\src\Illuminate\Routing\Router.php"
      line: "650 to 652"
    }
    +attributes: ParameterBag {#45
      #parameters: []
    }
    +request: ParameterBag {#51
      #parameters: array:3 [
        "loaderId" => "1111"
        "postCategory" => "0"
        "sortBy" => "created_at+"
      ]
    }
    +query: ParameterBag {#51}
    +server: ServerBag {#47

...

我的过滤器范围:

<?php
namespace App\Filters;

use Illuminate\Database\Eloquent\Builder;

trait Filterable
{
    public function scopeFilter($query, QueryFilters $filters)
    {
        return $filters->apply($query);
    }
}

标签: phplaravel

解决方案


推荐阅读