我正在按照教程编写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在这些课程中做了什么吗?
答案 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 ,在
中调用