Laravel 5 eager loading dropping leading zeros from foreign key

落花浮王杯 提交于 2019-12-24 01:17:41

问题


I believe that I've encountered a bug in how Laravel 5.3 handles eager loading when the foreign key is a string which contains zerofilled numbers.

I have two models (using a mysql backend), School and Student. The id field in School is a string, and contains 5-digit numbers assigned by the state, which include leading zeros. Student BelongsTo School, and contains a school_id field which is defined identically to the id field in School. I have done some testing, and I'm finding that when I call Student::with('school') I get the expected School models as long as the school_id in Student is free of leading zeroes, but it returns no School models for school_id values with leading zeroes.

I've done direct testing with freshly minted School records, and the values are being stored correctly with leading zeroes in both database tables, and when I try directly querying the tables the leading zeroes work fine, but as soon as with() enters the equation, things break. I've attempted to reproduce the failure through other means, even manually constructing whereIn() calls to mirror syntax of the queries constructed by with(), but everything else correctly returns the expected records.

This code worked fine prior to climbing the Laravel upgrade ladder from 4.1 to 5.3, so I'm wondering what may have changed. I've gone as far as digging into the GitHub repository for BelongsTo, and none of the parameter handling seems to strip leading zeroes, so I'm really at a loss as to why with() is breaking in this way.

So, does anybody have any insights they can share? I'm stumped, and would rather not have to engineer around with(). I'll also state up front that I can't drop the leading zeroes from the id field, it's not an option, they must actually be stored, and not just displayed as with ZEROFILL.

UPDATE: I've attached an example that establishes that the school_id stored in Student can successfully connect to the corresponding School when used separately from the with() statement:

    $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));

Here are the (edited for brevity) results of the \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
            )
        )
    )
)

So, while Student::with('school') fails to pull up the corresponding School, feeding the same Student->school_id values to School::whereIn() succeeds. I remain mystified.


回答1:


You are not showing the model classes, but my guess is you need public $incrementing = false; in the School Eloquent model. Otherwise it will be coerced to int when matching the relationship, losing all leading zeroes.



来源:https://stackoverflow.com/questions/45492898/laravel-5-eager-loading-dropping-leading-zeros-from-foreign-key

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!