yiisoft / yii2

Yii 2: The Fast, Secure and Professional PHP Framework

Home Page:http://www.yiiframework.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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?