【问题标题】:Method Illuminate\Database\Query\Builder::filter does not exist方法 Illuminate\Database\Query\Builder::filter 不存在
【发布时间】:2018-03-31 19:02:16
【问题描述】:

我正在按照教程编写 2 个用于过滤论坛应用程序中的线程的类。我遇到了这个错误

 $threads = Thread::latest()->filter($filters); // in 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 扩展了过滤器类:

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

}

如果我将 latest 更改为 all,我会收到此 错误

类型错误:参数 1 传递给 Illuminate\Support\Collection::filter() 必须是可调用的或为空的, 给定对象,调用

还有谁能解释一下 $builder 在这些类中做什么?

【问题讨论】:

    标签: php laravel


    【解决方案1】:

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

    filter() 是 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();
    

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

    【讨论】:

    • 我猜 getFilters 方法还有另一个问题。方法 Illuminate\Http\Request::intersect 不存在。顺便说一句,我正在关注 laracasts 教程
    • Request::intersect() 在 L5.5 中被移除。尝试改用only($this-&gt;filters)
    • 您好,谢谢,当我尝试使用以下用户名过滤时:forum.me/threads?by=username 我收到了对未定义函数 App\Filters\method_exist() 的调用
    【解决方案2】:

    如果您将 latest 更改为 all,您将获得 Laravel Collection。所以你在集合上调用filter() ($threads = Thread::all()-&gt;filter($filters);)。

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

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

    中调用

    【讨论】:

    • 提示:我的回答只回答你的第二条错误信息:)
    猜你喜欢
    • 2018-09-24
    • 2019-01-24
    • 2019-10-04
    • 2023-03-23
    • 1970-01-01
    • 2020-02-24
    • 1970-01-01
    • 1970-01-01
    • 2019-03-04
    相关资源
    最近更新 更多