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

Laravel Eloquent递归关联如何向所有嵌套层级传递查询条件

Laravel递归自关联全层级过滤实现方案

问题场景

你在项目中定义了User模型的自引用递归关联,初始模型代码如下:

class User extends Model
{
    public function children()
    {
        return $this->hasMany(self::class, 'level1_user_id')
            ->select(['id', 'first_name', 'last_name', 'level1_user_id']);
    }

    public function grandchildren()
    {
        return $this->children()->with(['grandchildren']);
    }
}

控制器查询时尝试给grandchildren关联增加first_name = rose的过滤条件,但条件仅对第一层关联生效,深层嵌套的关联节点不会被过滤,初始控制器代码如下:

public function allChildren()
{
    $user = User::where('id', 3)->with(['grandchildren' =>
        function ($query) {
            $query->where('first_name', 'rose');
        }
    ])->first();
    return $user;
}

你尝试修改grandchildren方法接收外部传入的查询对象透传到嵌套层的写法不符合Eloquent关联的调用规则,无法正常生效,错误尝试代码如下:

class User extends Model
{
    public function children()
    {
        return $this->hasMany(self::class, 'level1_user_id')
            ->select(['id', 'first_name', 'last_name', 'level1_user_id']);
    }

    public function grandchildren(Query $inputQuery)
    {
        return $this->children()->with(['grandchildren' => function ($query) use ($inputQuery) {
        $query->$inputQuery;
    }]);
    }
}

错误原因

Eloquent在渴求式加载、懒加载关联时,会自动无参调用关联方法获取关系定义,带参数的关联方法会被框架直接调用触发参数缺失错误,同时默认的with闭包只会作用在当前层关联,不会自动透传到递归嵌套的下一层。

实现代码

不需要修改原有模型的关联定义,直接通过闭包递归引用的方式,就能让过滤条件作用到所有递归层级,控制器代码调整如下:

public function allChildren()
{
    // 定义过滤闭包,通过引用传值持有自身引用,实现条件递归传递
    $filter = function ($query) use (&$filter) {
        $query->where('first_name', 'rose')
            ->with(['grandchildren' => $filter]); // 同一闭包传递给下一层关联
    };

    $user = User::where('id', 3)
        ->with(['grandchildren' => $filter])
        ->first();
    
    return $user;
}

逻辑说明

  • 闭包加&$filter引用传递后,每一层关联加载时,都会把同一个过滤规则绑定到下一层的grandchildren关联上,从第一层到最深层的所有关联查询都会带上first_name = rose的过滤条件
  • 如果需要复用这套过滤逻辑,可以把闭包封装成模型本地作用域,或者抽成公共查询方法,避免重复编写递归逻辑
  • 原有模型中无参数的grandchildren关联方法保留即可,不需要修改,无过滤需求的场景可以直接正常调用

内容的提问来源于stack exchange,提问作者nasim jahednia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 23:01:38