active-record
active-record copied to clipboard
Support relations via `array` type columns
Currently AR supports scalar to array relations:
$this->hasMany(Item::class, ['id' => 'item_ids'])
where id is integer column
and item_ids is integer array column
But AR does not support array to scalar relations
$this->hasMany(Promotion::class, ['item_ids' => 'id'])
The reason is in preparing the query condition. Currently it is only IN condition
https://github.com/yiisoft/active-record/blob/b000730e35c7dad0b6796bf0459c5fae017699d8/src/ActiveRelationTrait.php#L636
Which will generate condition like id IN (1, 2, 3)
But for array column this should be arrays overlap condition like item_ids && ARRAY[1, 2, 3] (Postgres)
To solve the issue it requires:
- Realize
ArrayOverlapConditionandJsonOverlapCondition(for json arrays) in db packages - Add
AR::columnType($columnName)method to get type of the column - Prepare condition according to the column type:
match ($columnType) {
'array' => $this->andWhere(new ArrayOverlapCondition($attributes, $values)),
'json' => $this->andWhere(new JsonOverlapCondition($attributes, $values)),
default => $this->andWhere(['in', $attributes, $values]),
};
What's the support in other DBs?
What's the support in other DBs?
Pgsql,Mssql,Oraclesupportarraysbutdbpackage has realization only forPgsql;Mysql,Pgsql,Sqlite,Mssql,Oraclesupportjsonbutdbpackage has realization only forMysql,Pgsql,Sqlite. But it may not be possible to implementJsonOverlapConditionfor all DBMSs. At least forMysqlandPgsqlit is easy to implement.
If it's MySQL and PostgreSQL then it is worth doing.
Done with #375