You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:00:00