Почему модель загружается, в то время как где ложь?

#laravel

Вопрос:

У меня есть такой запрос:

 $result = PortingItem::whereHas('porting', function ($query) {
        $query->whereIn('status', [
            Porting::STATUS_REQUESTED,
            Porting::STATUS_ACCEPTED,
            Porting::STATUS_DELAYED,
        ]);
    })->where(function ($query) use ($numbers) {
        $query->whereBetween('phone_number_start', [$numbers[0], $numbers[1]])
            ->orWhereBetween('phone_number_end', [$numbers[0], $numbers[1]]);
    })->orWhere([
        ['phone_number_start', '<=', $numbers[0]],
        ['phone_number_end', '>=', $numbers[1]],
    ])->get();
 

PortingItem Модель по-прежнему возвращает результат запроса, в то время как отношение переноса пустое. Я не понимаю, почему это происходит.

Это мое Porting образцовое отношение

 public function items()
{
    return $this->hasMany(PortingItem::class);
}
 

Это мое PortingItem образцовое отношение:

 public function porting()
{
    return $this->belongsTo(Porting::class);
}
 

Ответ №1:

Вы всегда должны группировать orWhere вызовы, чтобы избежать неожиданного поведения при применении глобальных областей.

 $result = PortingItem::whereHas('porting', function ($query) {
        $query->whereIn('status', [
            Porting::STATUS_REQUESTED,
            Porting::STATUS_ACCEPTED,
            Porting::STATUS_DELAYED,
        ]);
    })->where(function ($query) use ($numbers) {
        $query->where(function ($query) use ($numbers) {
            $query->whereBetween('phone_number_start', [$numbers[0], $numbers[1]])
                ->orWhereBetween('phone_number_end', [$numbers[0], $numbers[1]]);
        })->orWhere(function ($query) use ($numbers) {
            $query->where('phone_number_start', '<=', $numbers[0])
                ->where('phone_number_end', '>=', $numbers[1]);
        });
    })->get();
 

https://laravel.com/docs/8.x/queries#logical-grouping