Laravel Eloquent获取不重复随机行及whereNotIn报错求助
多页问卷随机获取未展示数据的Eloquent解决方案
错误原因
你遇到的Nested arrays may not be passed to whereIn method错误,是因为$this->qs本身就是一维数组(比如[1,3,8]),但你在whereNotIn里用[$this->qs]把它又包了一层,变成了二维数组[[1,3,8]],而Eloquent的whereNotIn方法要求传入一维数组作为排除条件,所以触发了这个错误。
另外原有逻辑存在漏洞:先随机生成ID再判断是否在排除列表,可能会抽到已经展示过的ID,导致重复展示或者无效查询。
最优实现方案
直接让数据库查询时排除已展示的ID,并随机返回一条未展示的记录,既避免重复又更高效:
// 从Session获取已展示的问卷ID数组,默认空数组 $shownIds = $request->session()->get('arrayOfQs', []); // 查询未展示的随机问卷 $question = Ctest::whereNotIn('id', $shownIds) ->inRandomOrder() ->first(); if ($question) { // 将新问卷ID加入已展示数组并更新Session $shownIds[] = $question->id; $request->session()->put('arrayOfQs', $shownIds); } else { // 所有问卷都已展示完毕的处理逻辑 // 比如重置Session或者提示用户 $request->session()->forget('arrayOfQs'); // return response()->json(['message' => '所有问卷已展示完毕']); } // 后续处理$question...
保留随机数生成逻辑的修正方案
如果坚持要自己生成随机数,需先判断生成的ID是否在排除列表里,直到拿到未展示的ID,同时修正whereNotIn的参数:
$shownIds = $request->session()->get('arrayOfQs', []); $randomId = $this->generateRandInt($request)['randomInt']; // 循环直到拿到未展示的ID while (in_array($randomId, $shownIds)) { $randomId = $this->generateRandInt($request)['randomInt']; } // 正确查询:直接传入一维数组$shownIds,不需要额外包裹 $question = Ctest::whereNotIn('id', $shownIds) ->find($randomId); // 更新Session数组 $shownIds[] = $randomId; $request->session()->put('arrayOfQs', $shownIds);
注意:这种方法在接近所有问卷都展示完时,可能会多次循环生成随机数,效率不如直接让数据库随机查询的方案。
内容的提问来源于stack exchange,提问作者Mephisto
相关产品推荐
相关产品推荐

