Laravel 5.5+Yajra Datatable 8*调用where方法报不存在错误求助
问题原因分析
你遇到的Method where does not exist错误,核心原因是你先把数据库查询转换成了Eloquent集合,再尝试对DataTables实例调用查询构建器的where方法——而基于集合的DataTables实例并不支持这个方法。
具体来说:
Expenses::with(...)->orderBy(...)->get()这行代码执行后,$data已经是一个Eloquent集合(Illuminate\Database\Eloquent\Collection),而不是查询构建器实例。- 当你用
DataTables::of($data)创建DataTables实例时,它是针对集合的处理模式,此时调用$datatables->where()就会报错,因为集合没有这个方法,只有查询构建器才有。
解决方法
推荐两种方案,优先选第一种(性能更优):
方案一:在查询构建器阶段添加日期过滤(推荐)
把日期过滤逻辑放到get()之前,也就是在数据库层面完成数据过滤,这样只会拉取符合日期条件的数据,性能更好:
public function getExpensesHistory(Request $request){ // 先创建查询构建器实例,不要先调用get() $query = Expenses::with([ 'expenses' => function ($query) { $query->select('id', 'type_name'); }, 'user' => function ($query) { $query->select('id', 'name'); } ])->orderBy('exp_date','desc'); // 处理日期过滤条件 $from_date = $request->get('from_date'); $end_date = $request->get('end_date'); if (!empty($from_date) && !empty($end_date)) { // 转换日期格式并添加到查询构建器 $formatted_from = date('Y-m-d', strtotime($from_date)); $formatted_end = date('Y-m-d', strtotime($end_date)); $query->where('exp_date', '>=', $formatted_from) ->where('exp_date', '<=', $formatted_end); } // 把查询构建器传给DataTables return DataTables::of($query)->make(true); }
方案二:如果必须用集合处理,使用filter方法
如果你因为某些原因必须先获取全量集合再过滤,可以用集合的filter方法替代where:
public function getExpensesHistory(Request $request){ $data = Expenses::with([ 'expenses' => function ($query) { $query->select('id', 'type_name'); }, 'user' => function ($query) { $query->select('id', 'name'); } ])->orderBy('exp_date','desc')->get(); $datatables = DataTables::of($data); $from_date = $request->get('from_date'); $end_date = $request->get('end_date'); if (!empty($from_date) && !empty($end_date)) { $formatted_from = date('Y-m-d', strtotime($from_date)); $formatted_end = date('Y-m-d', strtotime($end_date)); // 用filter过滤集合 $datatables->filter(function ($expense) use ($formatted_from, $formatted_end) { return $expense->exp_date >= $formatted_from && $expense->exp_date <= $formatted_end; }); } return $datatables->make(true); }
额外注意事项
- 记得先判断
from_date和end_date是否为空,避免空值转换日期时出现错误。 - 方案一的性能远优于方案二,因为它直接在数据库层面过滤数据,减少了内存占用和数据传输量,建议优先使用。
内容的提问来源于stack exchange,提问作者Awadhesh Kumar
相关产品推荐
相关产品推荐

