-
-
Notifications
You must be signed in to change notification settings - Fork 36
Incorrect relation queries #549
Copy link
Copy link
Open
Labels
status:ready for adoptionFeel free to implement this issue.Feel free to implement this issue.type:bugBugBug
Description
Description
Related queries created to query main table instead of related one.
Sample classes
final class BrazilCep extends ActiveRecord
{
public string $cep;
public ?int $city_id;
public function getTableName(): string
{
return '{{%brazil_cep}}';
}
public static function query(ActiveRecordInterface|string|null $modelClass = null): BrazilCepQuery
{
return new BrazilCepQuery(static::class);
}
public function relationQuery(string $name): ActiveQueryInterface
{
return match ($name) {
'city' => $this->hasOne(BrazilCity::class, ['id' => 'city_id']),
default => parent::relationQuery($name),
};
}
public function getCity(): ?BrazilCity
{
return $this->relation('city');
}
}
final class BrazilCity extends ActiveRecord
{
public int $id;
public string $name;
public function getTableName(): string
{
return '{{%brazil_city}}';
}
public static function query(ActiveRecordInterface|string|null $modelClass = null): BrazilCityQuery
{
return new BrazilCityQuery(static::class);
}
}
final class BrazilCityQuery extends BaseActiveQuery
{
}
final class BrazilCepQuery extends BaseActiveQuery
{
}Code to reproduce
$cep = BrazilCep::query()->byCep($cep)->one();
// exists, $cep->city_id === 8966.
$cityName = $cep->getCity()?->name;
// SQL Error: Undefined column: 7 ERROR: column \"id\" does not exist SELECT * FROM \"brazil_cep\" WHERE \"id\"=8966
$query = $cep->relationQuery('city')
// returns BrazilCepQuery instead of BrazilCityQuerythe root cause is \Yiisoft\ActiveRecord\AbstractActiveRecord::createQuery:
public function createQuery(ActiveRecordInterface|string|null $modelClass = null): ActiveQueryInterface
{
// for `city` relation it's called with `BrazilCity` as argument from `BrazilCep` class instance, so BrazilCepQuery is created instead of correct BrazilCityQuery
return static::query($modelClass ?? $this);
}proposed fix:
public function createQuery(ActiveRecordInterface|string|null $modelClass = null): ActiveQueryInterface
{
$source = $modelClass ?? $this;
return source::query(source);
}Package version
1.0.2
PHP version
8.4.14
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
status:ready for adoptionFeel free to implement this issue.Feel free to implement this issue.type:bugBugBug