Laravel Eloquent关联查询问题:筛选无近期预约的用户
问题解决:筛选未来一周无预约的用户
第一个错误的原因
你定义的reservation()关联用了BelongsTo,但给外键传了数组['user_1_id', 'user_2_id', 'user_3_id', 'user_4_id']——BelongsTo是一对一关联,只支持单个外键字段,Laravel内部处理时把数组当成字符串参数传递,才触发了str_contains(): Argument #1 ($haystack) must be of type string, array given错误。
你的场景是一个预约记录(Reservation)对应多个用户(分散在user_1到user_4_id字段),这种关系没法用常规的BelongsTo/HasMany直接定义,得用自定义查询逻辑。
解决方案:筛选无预约用户
方法一:先查有预约的用户ID,再排除
先找出未来一周内所有出现在预约记录里的用户ID,再从用户表中排除这些ID:
use Carbon\Carbon; // 1. 获取未来一周内有预约的所有用户ID $reservedUserIds = Reservation::whereBetween('date', [Carbon::now(), Carbon::now()->addWeek()]) ->select('user_1_id', 'user_2_id', 'user_3_id', 'user_4_id') ->get() // 把四个用户ID字段扁平化,过滤空值,去重 ->flatMap(fn($res) => collect([$res->user_1_id, $res->user_2_id, $res->user_3_id, $res->user_4_id])->filter()) ->unique() ->toArray(); // 2. 查询没有预约的用户 $availableUsers = User::whereNotIn('id', $reservedUserIds)->get();
方法二:直接用数据库层面的不存在查询(性能更优)
不需要先获取ID集合,直接在数据库层面过滤掉有预约的用户,适合数据量大的场景:
use Carbon\Carbon; $availableUsers = User::whereDoesntExist(function ($query) { $query->from('reservations') ->whereBetween('date', [Carbon::now(), Carbon::now()->addWeek()]) ->where(function ($sub) { $sub->whereColumn('reservations.user_1_id', 'users.id') ->orWhereColumn('reservations.user_2_id', 'users.id') ->orWhereColumn('reservations.user_3_id', 'users.id') ->orWhereColumn('reservations.user_4_id', 'users.id'); }); })->get();
内容的提问来源于stack exchange,提问作者Keygun2k1
相关产品推荐
相关产品推荐

