Yii2: Convert hasMany() relation into hasOne()

428 Views Asked by At

I need to be able to convert a hasMany() relation, which queries and return an array into a hasOne() relation which returns object|null.

Use case:

public function getItems() : \yii\db\ActiveQuery {
    return $this->hasMany(Item::class, ['parent_id' => 'id']);
}

I want to create a relation which returns one specific Item object (or null if it does not exist).

I would like to do something like this:

public function getPrimaryItem() : \yii\db\ActiveQuery {
    return $this->getItems()->andWhere(["primary"=>true])->toHasOne();
}

Please do not tell me to call ->one() on the original query, because that is not going to solve the problem. I need to be able to:

  • call $model->primaryItem and receive either Item or null
  • call $model->getPrimaryItem() and receive the relation's ActiveQuery
2

There are 2 best solutions below

0
On BEST ANSWER

You can toggle it by multiple property of \yii\db\ActiveQuery

public function getPrimaryItem() : \yii\db\ActiveQuery {
    $query =  $this->getItems();
    $query->multiple = false;

    //Your logics
    $query->andWhere(["primary"=>true])

    return $query;
}
1
On

You can just change hasMany to hasOne call and then add where filter to query; it's to return the first row found then

public function getPrimaryItem() : \yii\db\ActiveQuery {
    return $this->hasOne(Item::class, ['parent_id' => 'id'])->where(["primary" => true]);
}