Activerelation Oncondition

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]

How can I solve this?

Thanks!

PD: Yii2 Is awesome! ^^

I can’t think of a good way to solve this. Perhaps you have to write JOIN explicitly for this special case.

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.