M
M
Maxim2018-09-20 01:10:41
Yii
Maxim, 2018-09-20 01:10:41

How to apply a method from a model in Active Query?

Good night all!
A very long time ago I asked a question on a similar topic: Active Query how to apply a function from a model? , but did not decide this moment for himself. It seems that the answers are correct, but I asked the question incorrectly, so I did not receive a proper answer. Now I'm asking it again.
Request:

$certifications = Certification::find()
            ->joinWith(['user', 'profile'])
            ->andWhere([User::tableName().'.status' => User::STATUS_ACTIVE])
            ->andWhere('CONCAT_WS(" ", '.Profile::tableName().'.last_name, '.Profile::tableName().'.name, '.Profile::tableName().'.middle_name) LIKE :search')
            ->params([':search' => '%' . $search . '%'])
            ->orderBy([Profile::tableName().'.last_name' => 'SORT_ASC', Profile::tableName().'.name' => 'SORT_ASC'])
            ->limit(8)
            ->isValid() //?? метод из модели CertificationQuery
            ->all();

Active Query Model (CertificationQuery)
public function isValid()
    {
        $this->andWhere(['<=',  'date_from',  'здесь рассчитываемая из модели обратная дата (getReverseEndDate())']);
    }

Certification method and models to apply
/**
     * Получаем обратную дату окончания действия категории
     * @return string
     */
    public function getReverseEndDate(): string
    {
        $date = date_create($this->date_from); //подготавливаем дату для рассчёта срока
        $date = date_modify($date, '-'.$this->category->duration_months.'month'); //Вычитаем дату от текущей
        return Yii::$app->formatter->asTimestamp($date);
    }

Question:
  1. How can I apply a method getReverseEndDate()from a model in Active Query?
  2. Please correct me if I'm miscalculating the date. I need to add months.

I draw your attention to the fact that the method is in the model with which we make the request. Thanks to!

Answer the question

In order to leave comments, you need to log in

2 answer(s)
M
Maxim Kozhin, 2018-09-20
@myks92

I would add an additional link to the model by a valid date:

class Certification extends ActiveRecord...
{
//...

/**
* Получаем обратную дату окончания действия категории
* @return string
*/
public function getReverseEndDate(): string
{
    $date = date_create($this->date_from); //подготавливаем дату для рассчёта срока
    $date = date_modify($date, '-'.$this->category->duration_months.'month'); //Вычитаем дату от текущей
    return Yii::$app->formatter->asTimestamp($date);
}

public function getValidCategory()
{
    return $this->hasOne(Category::className(), ['id' => 'category_id'])
        ->andWhere(['<=',  'date_from',  'reverseEndDate']);
}

And then would JOIN (join with valid category) on this relation.
NULL are eliminated automatically
$certifications = Certification::find()
            ->joinWith(['user', 'profile', 'validCategory'])
            ->andWhere([User::tableName().'.status' => User::STATUS_ACTIVE])
            ->andWhere('CONCAT_WS(" ", '.Profile::tableName().'.last_name, '.Profile::tableName().'.name, '.Profile::tableName().'.middle_name) LIKE :search')
            ->params([':search' => '%' . $search . '%'])
            ->orderBy([Profile::tableName().'.last_name' => 'SORT_ASC', Profile::tableName().'.name' => 'SORT_ASC'])
            ->limit(8)
            #->isValid() //?? метод из модели CertificationQuery уже не нужен
            ->all();

A
Andrey, 2018-09-20
@VladimirAndreev

pass an instance of the model to ActiveQuery. there something from $this is taken, so a simple (new Certification())->getReverseEndDate() won't work.
but in general, IMHO, there should not be logic in models, all logic should be in their Query ...

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question