Relational queries populating invalid models when foreign key / linking value is 0
BVBAccelm opened this issue · comments
Yii's functionality to join / populate relations on a model doesn't work properly in circumstances where the foreign key (linking value) is a 0. The issue stems from here ( https://github.com/yiisoft/yii2/blob/master/framework/db/ActiveRelationTrait.php#L314 ). The getModelKey can return false when there is no value. The line in question:
$value = isset($buckets[$key]) ? $buckets[$key] : ($this->multiple ? [] : null);
will return an item in that array with index 0 ($buckets[false] === $buckets[0]
) instead of null which it should.
What steps will reproduce the problem?
Create two database tables, user
and person
. Table user
has id
, and email
. Table person
has user_id
and name
where user_id
is not a required field.
Create the active record models and relations for them, populate a dozen records into each table, making sure that the user
table has a record with id
value 0. Make sure one record in the person
table has user_id
0, and make several of those records have user_id
as null.
Using an Active Query perform one like:
$models = Person::find()->with(['user'])->all();
What is the expected result?
All Person models that have user_id
as null should not have a related model populated for the user relation.
What do you get instead?
All Person models that have user_id
as null end up having the user
record with id
0 populated.
Additional info
Not really sure the best way to handle this. Everything I've checked ends up having $arr[false] === $arr[0]. So I'm not sure how you can differentiate one from the other. Maybe this line:
$value = isset($buckets[$key]) ? $buckets[$key] : ($this->multiple ? [] : null);
Should become:
$value = $key !== false && isset($buckets[$key]) ? $buckets[$key] : ($this->multiple ? [] : null);
but I'm honestly not sure if that has unwanted side effects. I can't imagine a scenario where someone would have a value indexed with false, but maybe someone more involved with the project would.
Indeed. Do you have time to fix it maybe?