Laravel 5 с нетерпением загружает начальные нули из внешнего ключа

Я полагаю, что столкнулся с ошибкой в ​​том, как Laravel 5.3 обрабатывает нетерпеливую загрузку, когда внешний ключ представляет собой строку, содержащую заполненные нулями числа.

У меня есть две модели (с использованием бэкэнда mysql), School и Student. Поле id в School представляет собой строку и содержит 5-значные числа, назначенные штатом, включая ведущие нули. Student BelongsTo School и содержит поле school_id, которое определено идентично полю id в School. Я провел некоторое тестирование и обнаружил, что при вызове Student::with('school') я получаю ожидаемые модели School, если school_id в Student не содержит ведущих нулей, но он не возвращает моделей School для значений school_id с ведущими нулями.

Я провел прямое тестирование со свежеиспеченными записями School, и значения сохраняются правильно с ведущими нулями в обеих таблицах базы данных, и когда я пытаюсь напрямую запросить таблицы, ведущие нули работают нормально, но как только with() входит в уравнение, вещи ломаются. Я пытался воспроизвести сбой другими способами, даже вручную создав вызовы whereIn() для зеркального синтаксиса запросов, созданных with(), но все остальное правильно возвращает ожидаемые записи.

Этот код отлично работал до подъема по лестнице обновления Laravel с 4.1 до 5.3, поэтому мне интересно, что могло измениться. Я зашел так далеко, что покопался в репозиторий GitHub для BelongsTo, и ни один из параметров обработки, похоже, не удаляет начальные нули, поэтому я действительно в недоумении, почему with() ломается таким образом .

Итак, есть ли у кого-нибудь идеи, которыми они могут поделиться? Я в тупике и предпочел бы не проектировать вокруг with(). Также сразу оговорюсь, что я не могу отбрасывать начальные нули из поля id, это не вариант, их надо реально хранить, а не просто отображать как при ZEROFILL.

ОБНОВЛЕНИЕ: я приложил пример, который устанавливает, что school_id, хранящийся в Student, может успешно подключаться к соответствующему School при использовании отдельно от оператора with():

    $interventions = Intervention::with('school')->where('id','=',780)->get();
    $schools = School::whereIn('id',$interventions->pluck('school_id')->all())->get();
    throw new \Exception(print_r($interventions,true).'|'.print_r($schools,true));

Вот (отредактированные для краткости) результаты \Exception:

Exception in AdminController.php line 273:
Illuminate\Database\Eloquent\Collection Object
(
    [items:protected] => Array
    (
        [0] => App\Models\Student Object
        (
            [attributes:protected] => Array
            (
                [id] => 780
                [school_id] => 01234
            )
            [relations:protected] => Array
            (
                [school] => 
            )
        )
    )
)


Illuminate\Database\Eloquent\Collection Object
(
    [items:protected] => Array
    (
        [0] => App\Models\School Object
        (
            [attributes:protected] => Array
            (
                [id] => 01234
                [school] => Test1
                [district_id] => 81000
                [inactive] => 0
                [see] => 0
            )
        )
    )
)

Таким образом, хотя Student::with('school') не удается получить соответствующий School, передача тех же значений Student->school_id в School::whereIn() завершается успешно. Я остаюсь озадаченным.


person dspitzle    schedule 03.08.2017    source источник


Ответы (1)


Вы не показываете классы моделей, но я предполагаю, что вам нужно public $incrementing = false; в модели School Eloquent. В противном случае он будет приведен к типу int при сопоставлении отношения, потеряв все начальные нули.

person alepeino    schedule 14.08.2017
comment
О, это «хорошо»! У меня было ощущение, что что-то происходит конкретно с сопоставлением, поскольку синтаксис запроса, похоже, возвращает правильные записи. Я проведу некоторые тесты и отчитаюсь. - person dspitzle; 14.08.2017
comment
Ага, так и получилось! Я почти уверен, что когда я впервые создал это в Laravel 4.1, об этом не упоминалось, но я могу ошибаться. Спасибо за ответ. - person dspitzle; 14.08.2017