Как при вызове hasOne/hasMany вызывать функцию класса с которого мы берем данные?

В фреймворке Yii, при использовании методов hasOne и hasMany для установки отношений между моделями, мы имеем возможность вызывать функции класса, с которого мы берем данные.

Один из способов сделать это - использовать коллбэк-функции, предоставляемые Yii для определения поведения при выполнении определенных событий.

Для этого нам нужно определить методы в классе-модели, которые будут автоматически вызываться при установке этих отношений.

Например, предположим, у нас есть две модели: User и Profile. Каждый пользователь User имеет только одну запись Profile. Для этого мы можем использовать метод hasOne в классе User:

public function getProfile()
{
    return $this->hasOne(Profile::class, ['user_id' => 'id']);
}

В классе Profile мы можем определить метод afterFind, который будет вызываться после получения данных модели из базы данных:

public function afterFind()
{
    parent::afterFind();
    
    // Вызываем нужную функцию
    $this->doSomeAction();
}

Теперь, когда мы обращаемся к свойству profile у модели User, метод afterFind класса Profile будет автоматически вызываться и выполнять нужные действия.

Аналогичным образом, можно использовать метод hasMany для установки отношений, возвращающих множество объектов.

Важно отметить, что использование коллбэк-функций подразумевает то, что логика будет применяться к каждой записи, возвращенной при обращении к свойству отношения. Если же мы хотим вызвать функцию только один раз при загрузке модели, мы можем воспользоваться методом findWith(), который помимо связанных данных также загружает связанные объекты в память:

public function getUserWithProfile($id)
{
    return User::find()->with('profile')->where(['id' => $id])->one();
}

Таким образом, при использовании методов hasOne и hasMany в Yii, мы можем использовать коллбэк-функции классов, чтобы вызывать функции из классов, от которых мы берем данные. Это предоставляет гибкость и позволяет нам добавлять дополнительную логику при работе с данными.