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

Laravel中如何通过Eloquent模型实现基于数据透视表过滤的假期数据查询

用Laravel Eloquent实现指定经理下属用户的假期查询

嘿,我来帮你把原来的DB查询构造器写法转换成更优雅的Eloquent实现~首先得先修正模型里的一个小细节,然后再看两种不同的查询方式:

第一步:修正模型关联的透视表名

你描述里的透视表是user_manager,但当前Manager和User模型里的关联用的是employee_manager,这会导致关联找不到数据,先把这个改掉:

修改Manager模型:

class Manager extends Model
{
    use HasFactory;
    protected $table = 'managers';
    protected $fillable = ['user_id'];

    public function users()
    {
        // 把第二个参数改成你的透视表名user_manager
        return $this->belongsToMany(User::class, 'user_manager')->withTimestamps();
    }
}

修改User模型:

class User extends Model
{
    use HasFactory, Notifiable;

    public function managers()
    {
        // 同样改成user_manager
        return $this->belongsToMany(Manager::class, 'user_manager')->withTimestamps();
    }

    // 新增与Vacation模型的关联(因为要通过用户找假期)
    public function vacations()
    {
        return $this->hasMany(Vacation::class, 'user_id');
    }
}

第二步:两种Eloquent查询方式

方式一:从Vacation模型出发(推荐,单查询更高效)

直接通过whereHas嵌套关联,筛选出属于指定经理下属用户的假期:

$managerId = $id; // 你的指定manager id
$vacations = Vacation::whereHas('user.managers', function ($query) use ($managerId) {
    $query->where('managers.id', $managerId);
})->get();

这个写法会生成一条高效的SQL查询,直接过滤出符合条件的假期,避免N+1问题。

方式二:从Manager模型出发

如果你想先拿到经理对象,再获取其下属的所有假期,可以这么写:

$manager = Manager::findOrFail($id);
// 先获取经理的所有用户,预加载假期,再提取并合并所有假期
$vacations = $manager->users()
    ->with('vacations') // 预加载避免N+1
    ->get()
    ->pluck('vacations') // 提取每个用户的假期集合
    ->flatten(); // 把多维集合转成一维

这种写法更直观,但如果下属用户很多,会先查询用户,再批量查询假期(因为用了with,所以是2条查询),性能也不错,适合需要同时处理用户和假期数据的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 02:47:34