
在 Laravel 中,若使用 new Model() 初始化模型实例后进行链式查询(如 whereIn、with),会导致后续查询方法无效;必须改用 Model::query() 获取查询构建器实例,才能正确支持链式操作和关系预加载。
在 laravel 中,若使用 `new model()` 初始化模型实例后进行链式查询(如 `wherein`、`with`),会导致后续查询方法无效;必须改用 `model::query()` 获取查询构建器实例,才能正确支持链式操作和关系预加载。
你遇到的问题非常典型:代码看似逻辑清晰,却因底层对象类型错误而“静默失败”。核心原因在于——new User() 创建的是一个 Eloquent 模型实例(即单条记录的容器),而非查询构建器(QueryBuilder)。它不支持 where、whereIn、with 等链式查询方法;这些方法实际定义在 Illuminate\Database\Eloquent\Builder 类中,只有通过 User::query() 或 User::where(...) 等静态入口返回的对象才具备完整查询能力。
例如,以下写法是错误的:
$users = new User(); // ❌ 返回 User 实例(Eloquent\Model),非 Builder
$users->whereIn('id', $viewedIds); // ⚠️ 此调用无效果(方法存在但不修改查询状态)
$rdata = $users->with('profile')->where('gender', $searchGender)->simplePaginate(8); // ❌ 最终执行的 SQL 不含 whereIn 条件而正确做法是始终从查询构建器起点出发:
// ✅ 正确:获取 Eloquent Builder 实例,支持完整链式操作
$users = User::query();
// 可安全叠加任意查询约束(顺序无关紧要,Builder 会累积条件)
$users->whereIn('id', $viewedIds);
$users->where('gender', $searchGender);
$users->with('profile');
$users->orderBy('last_login');
$rdata = $users->simplePaginate(8); // 所有条件均生效更简洁、推荐的写法(函数式链式风格):
$rdata = User::query()
->whereIn('id', $viewedIds)
->where('gender', $searchGender)
->with('profile')
->orderBy('last_login')
->simplePaginate(8);⚠️ 关键注意事项:
- User::where(...)、User::whereIn(...) 等静态方法内部自动调用 query(),因此也完全可用;但 new User() 绝对不可用于构造查询。
- 若需动态拼接条件(如来自表单的可选搜索项),仍应基于 User::query() 起手,再按需 ->when($condition, fn($q) => $q->where(...))。
- 关系预加载(with)必须作用于查询构建器,而非模型实例——否则将触发 N+1 查询或直接报错。
总结:永远用 Model::query()(或其等价静态查询方法)开启查询,而非 new Model()。这是 Laravel Eloquent 查询链式调用可靠性的基石。










