Разработка модели базы данных с Laravel Eloquent - PullRequest
0 голосов
/ 22 января 2020

у нас есть проблема, чтобы запросить нашу базу данных обычным способом: Таблицы:

employees <1-n> employee_card_validity <n-1> card <1-n> stamptimes
id              id                           id         id
                employee_id                  no         card_id
                card_id                                 timestamp
                valid_from
                valid_to

Сотрудник сопоставляется с картой через сводную таблицу EmployeeCardValidity, которая имеет дополнительные атрибуты. Мы повторно используем карты, что означает, что карта имеет несколько записей в сводной таблице. Какая карта правильная, определяется valid_from / valid_to. Эти атрибуты ограничены, чтобы не перекрываться. Например, всегда есть уникальные отношения от сотрудника к временным штампам, когда у Сотрудника может быть несколько карт, и карта может принадлежать нескольким Сотрудникам с течением времени.

Нам не удается определить пользовательские отношения от Сотрудника к временным штампам, что касается какие штампы принадлежат сотруднику. Это означает, что когда я выбираю время штампа, его метка времени четко присваивается карте, потому что она находится внутри ее valid_from и valid_to.

Но я не могу определить подходящее отношение, которое дает мне все штампы для данного сотрудника. Единственное, что у меня есть, - это определить поле stati c в Employee и использовать его, чтобы ограничить отношение только выборками Stamptimes за указанное время.

public static $date = '';

public function cardsX() {
    return $this->belongsToMany('App\Models\Tempos\Card', 'employee_card_validity',
        'employee_id', 'card_id')
        ->wherePivot('valid_from', '>', self::$date);
}

Тогда я бы сказал в Controller :

\App\Models\Tempos\Employee::$date = '2020-01-20 00:00:00';
$ags = DepartmentGroup::with(['departments.employees.cardsX.stamptimes'])

Но я не могу сделать это динамически в зависимости от фактического результата запроса, как вы могли бы с помощью sql:

SELECT ecv.card_id, employee_id, valid_from, valid_to, s.timestamp 
FROM staff.employee_card_validity ecv 
join staff.stamptimes s on s.card_id = ecv.card_id 
and s.stamptimes between valid_from and coalesce(valid_to , 'infinity'::timestamp)
where employee_id = ?

Итак, мой вопрос: является ли база данных необычной или является картографом ORM, просто не способным описать такие отношения. Должен ли я в таких случаях использовать QueryBuilder / SQL? Подходит ли вам модель вашей базы данных в сторону ORM или в другую сторону?

1 Ответ

0 голосов
/ 24 января 2020

Вы можете попробовать:

DB::query()->selectRaw('*')->from('employee_card_validity')
    ->join('stamptimes', function($join) {
        return $join->on('employee_card_validity.card_id', '=', 'stamptimes.card_id')
                ->whereRaw('stamptimes.timestamp between employee_card_validity.valid_from and employee_card_validity.valid_to');
    })->where('employee_id', ?)->get();

Если ваш Laravel равен x> 5,5, вы можете запустить Model расширяет класс Pivot, я считаю, поэтому:

EmployeeCardValidity::join('stamptimes', function($join) {
        return $join->on('employee_card_validity.card_id', '=', 'stamptimes.card_id')
            ->whereRaw('stamptimes.timestamp between employee_card_validity.valid_from and employee_card_validity.valid_to');
})->where('employee_id', ?)->get();

Но код выше только перевод вашего sql запроса, я думаю, что смогу написать лучше, если точно знаю ваши варианты использования.

...