The documentatios says that [font="Courier New"]ActiveRelation::onCondition()[/font] sets the ON condition for the query. But currently it appends the condition with an "AND" to the default ON condition created by [font="Courier New"]ActiveRelationTrait[/font] using [font="Courier New"]ActiveRelationTrait::link[/font].
The relation I am trying to define is an 1:N with a custom ON condition: [font="Courier New"]a=:v OR b=:v[/font]
You mean a ActiveQuery instead an ActiveRelation? I would like to define it as an ActiveRelation in order to use its advantages over ActiveQuery and combine it with other relations.
If you look at the documentation of ActiveRelation::$on and ActiveRelation::onCondition() we can find the following description:
/**
* @var string|array the join condition. Please refer to [[Query::where()]] on how to specify this parameter.
* The condition will be used in the ON part when [[ActiveQuery::joinWith()]] is called.
* Otherwise, the condition will be used in the WHERE part of a query.
*/
public $on;
/**
* Sets the ON condition for the query.
* The condition will be used in the ON part when [[ActiveQuery::joinWith()]] is called.
* Otherwise, the condition will be used in the WHERE part of a query.
* [...]
*/
public function onCondition($condition, $params = [])
The ON condition will be used in the ON part. Otherwise, the condition will be used in the WHERE part of a query.
I think this is the behavior I expected but in fact ActiveQuery::joinWith() is appending the new condition to the default condition created using ActiveRelationTrait::$link.
This is how I defined my relation based upon the previous documentation:
/**
* @return \yii\db\ActiveRelation
*/
public function getHugs()
{
return $this->createActiveRelation([
'modelClass' => Hug::className(),
'primaryModel' => $this,
'multiple' => true,
])->onCondition('Hug.from=:id OR Hug.to=:id', [':id' => $this->id]);
}
But this doesn’t work because ActiveQuery::onCondition is not working as I expected and ActiveRelationTrait::$link is mandatory:
array_keys() expects parameter 1 to be array, null given
Error at line 196
private function filterByModels($models)
{
$attributes = array_keys($this->link);
A link is required in order to define a relation (otherwise many things will break, such as eager/lazy loading, link()/unlink()).
Your problem is that you want the link condition to be concatenated with on-condition via "OR". Technically there is no problem. The problem is mainly in how to express such a need. Since this requirement is not common, we do not want to introduce a new syntax to support it.