Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Relational queries populating invalid models when foreign key / linking value is 0 #20117

Open
BVBAccelm opened this issue Feb 19, 2024 · 1 comment
Labels
status:ready for adoption Feel free to implement this issue. type:bug Bug

Comments

@BVBAccelm
Copy link

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.

@bizley bizley added type:bug Bug status:ready for adoption Feel free to implement this issue. labels Feb 20, 2024
@bizley
Copy link
Member

bizley commented Feb 20, 2024

Indeed. Do you have time to fix it maybe?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status:ready for adoption Feel free to implement this issue. type:bug Bug
Projects
None yet
Development

No branches or pull requests

2 participants