Laravel Eager Load Ограничение проблемы - PullRequest
3 голосов
/ 30 октября 2019

Редактировать: для ясности, это Laravel 5.8.

Это приложение для HR, над которым я работаю.

Они запросили отчет, чтобы показать людей, которые в последний раз ударили кулаком. Конечно, не проблема, подумал я.

Итак, у меня есть форма с некоторыми пользовательскими параметрами, которые пользователь может указать, start_date, end_date, wage и массив отделов.

public function show()
{
    request()->validate([
        'start_date' => 'required|date|before_or_equal:today'
    ]);

    $start = Carbon::parse(request('start_date'));
    $end = request('end_date') ? Carbon::parse(request('end_date')) : today();
    $wage = request('wage');
    $departments = request('departments');

    $query = EmployeePunch::with([
        'employee' => function($query) use ($wage, $departments) {
            // IF I UN COMMENT THESE, IN THE FILTER BLOCK BELOW, THE EMPLOYEE BECOMES UNDEFINED.
            // if($wage != null) {
            //     $query->where('hourly', $wage);
            // }

            // if($departments) {
            //     $query->whereIn('department_id', $departments);
            // }
        },
        'employee.group',
        'employee.department'
    ])
    ->whereBetween('punch_time', [$start->startOfDay(), $end->endOfDay()])
    // only care about punch in for the day
    ->where('type', 1);

    $results = $query->get();

    $latePunches = $results->filter(function ($i) {
        $day = strtolower($i->punch_time->format('D'));
        $startTime = Carbon::parse(sprintf('%s %s', 
                                            $i->punch_time->format('d-m-Y'), 
                                            $i->employee->group[$day.'_start_time'])
                    );

        return $i->punch_time->isAfter($startTime) 
                && $i->punch_time->diffInMinutes($startTime) >= 5;
    });

    return view('hr.employeeLateReport.show', compact('latePunches'));
}

Итак, моя проблема в моей нетерпеливой загрузке, и я не могу понять это. Если я раскомментирую фильтры при активной загрузке сотрудников, в блоке фильтров в конце блока кода значение $i->employee станет неопределенным. Если пропустить фильтры, все работает персиково. Я проверил производимые запросы, и все это выглядит великолепно.

Любая помощь будет принята с благодарностью.

Вот методы связи

Employee.php

public function punches()
{
    return $this->hasMany(EmployeePunch::class);
}

public function group()
{
    return $this->belongsTo(Group::class);
}

public function department()
{
    return $this->belongsTo(Department::class)->withDefault();
}

EmployeePunch.php

public function employee()
{
    return $this->belongsTo(Employee::class);
}

Вывод SQL

sql

1 Ответ

5 голосов
/ 30 октября 2019

Попробуйте и используйте whereHas и гнездо whereBetween:

$query = EmployeePunch::with([
    'employee' => function($query) use ($wage, $departments) {
        if($wage != null) {
            $query->where('hourly', $wage);
        }

        if($departments) {
            $query->whereIn('department_id', $departments);
        }
    },
    'employee.group',
    'employee.department'
])->whereHas('employee', function($q) use($start, $end) {
    $q->whereBetween('punch_time', [$start->startOfDay(), $end->endOfDay()]);
})->where('type', 1);
...