使用laravel scout和tntsearch调用未定义的方法Illuminate \ Database \ Eloquent \ Builder :: search()

时间:2019-10-30 13:50:58

标签: php laravel eloquent laravel-scout

在我的larave-vue应用程序中,我希望能够使用laravel scout tntsearch按搜索词进行过滤,与此同时,我还要在控制器中执行其他过滤,排序或where子句。我无法同时在我的应用中正常工作。

在我的控制器中,我有这个:

$posts = Post::filter($filters)->search($request->input('query'))->paginate(0);
            $posts->load(['postcategory.section','author']);

            if($posts->isEmpty())
            {
                return response()->json([
                    'message' => 'No results found',
                ],500);    
            }

            return response()->json([
                'message' => 'Results found',
                'posts' => $posts,
            ]);

它给我以下错误:

Call to undefined method Illuminate\Database\Eloquent\Builder::search()

由于某种原因,它不起作用,我尝试更改过滤器,搜索和分页的顺序,但仍然出现错误。

如果您想知道我的filter方法是如何工作的,那基本上就是一个范围

您可以在此处阅读有关此内容的详细文章:

https://medium.com/@mykeels/writing-clean-composable-eloquent-filters-edd242c82cc8

以防万一,请参阅下面的QueryFilters和Filterable特征

<?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)
    {

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

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

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

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

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

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

        return $this->builder;
    }

    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();
    }

}

可过滤性状

<?php
namespace App\Filters;

use Illuminate\Database\Eloquent\Builder;

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

1 个答案:

答案 0 :(得分:0)

不会将search()方法添加到现有查询中,这是通过可搜索特征添加到模型中的方法

public static function search($query = '', $callback = null)
{
    return app(Builder::class, [
        'model' => new static,
        'query' => $query,
        'callback' => $callback,
        'softDelete'=> static::usesSoftDelete() && config('scout.soft_delete', false),
    ]);
}

该函数是静态的,它不会将查询构建器作为参数,并且无论如何都会返回一个新的构建器。因此,您无法将Search链接到查询上,但可以从搜索开始,然后应用过滤器

所以代替这个

$posts = Post::filter($filters)->search($request->input('query'))->paginate(0);

尝试一下

$posts = Post::search($request->input('query'))->filter($filters)->paginate(0);