方法Illuminate \ Database \ Query \ Builder :: filter不存在

时间:2018-03-31 19:02:17

标签: php laravel

我正在按照教程编写2个类来过滤论坛应用程序中的线程。我在行中出现了这个错误  $ threads = Thread :: latest() - > filter($ filters); (在threadscontroller中)

方法Illuminate \ Database \ Query \ Builder :: filter不存在。

带索引方法的ThreadsController:

<?php

namespace App\Http\Controllers;

use App\Thread;
use App\Channel;
use App\Filters\ThreadFilters;

use Illuminate\Http\Request;

class ThreadsController extends Controller
{

    public function __construct(){

        $this->middleware('auth')->only('store','create');

    }
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Channel $channel,ThreadFilters $filters)  
    {

$threads = Thread::latest()->filter($filters);  

if($channel->exist){
    $threads->where('channel_id',$channel->id);
}

$threads = $threads->get();

return view('threads.index',compact('threads'));



    }

这是抽象类过滤器:

<?php

namespace App\Filters;
use Illuminate\Http\Request;

abstract class Filters{

protected $request;
protected $builder;

protected $filters = [];

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



    }

    public function apply($builder){
        $this->builder = $builder;

        foreach($this->getFilters() as $filter=>$value){   //filter by,value yunus mesela.
if(method_exist($this,$filter)){    
    $this->$filter($value);  
}

        }

        return $this->builder;

    }


    public function getFilters(){

        return $this->request->intersect($this->filters); 
    } 

}

这里的ThreadFilters.php扩展了filter类:

<?php

namespace App\Filters;

use App\User;

use Illuminate\Http\Request;


class ThreadFilters extends Filters
{
protected $filters =['by'];        

protected function by($username){
    $user = User::where('name',$username)->firstorFail();

    return $this->builder->where('user_id',$user->id);



}

}

如果我更新所有,我收到此错误: 类型错误:传递给Illuminate \ Support \ Collection :: filter()的参数1必须是可调用的或null,给定对象,在

中调用

也有人可以解释一下$ builder在这些课程中做了什么吗?

2 个答案:

答案 0 :(得分:5)

latest()是一个修饰符快捷方式,相当于orderBy('created_at', 'desc')。它只是将ORDER BY约束添加到查询中。

filter()是Collection类的一个方法。该方法在查询构建器中不存在,因此您收到的“找不到方法”错误。

您的过滤器类似乎不应与生成的Collection一起使用。相反,它会为原始查询添加条件。尝试像这样实现它:

// Remove the filters() method here.
$threads = Thread::latest();  

if ($channel->exist) {
    $threads->where('channel_id', $channel->id);
}

// Pass your query builder instance to the Filters' apply() method.
$filters->apply($threads);

// Perform the query and fetch results.
$threads = $threads->get();

此外,对于未来的问题,包括您正在尝试/关注的教程可以为那些帮助您的人提供有益的背景。 :)

答案 1 :(得分:2)

如果您最新更改,则会获得Laravel Collection。因此,您在集合(filter())上调用$threads = Thread::all()->filter($filters);

如果您查看code,您会看到调用数组类的where()方法,该方法调用PHP的array_filter方法。如您所见,必须提供callable。 但是您将一个Object传递给过滤器方法$filters,它是一个ThreadFilters-Object - &gt;方法注入: public function index(Channel $channel,ThreadFilters $filters) ...

您的错误消息以一种很好的方式回答了您的问题: 类型错误:传递给Illuminate \ Support \ Collection :: filter()的参数1必须是可调用的或null, object object ,在

中调用