Как сделать связи в Yii2 между двумя моделями в разных модулях?

Всем добрый день.

Предположим, имеется некоторое расширение для Yii2, например, каталог, в котором имеется модель Orders, которую в свою очередь я хочу связать с моделью Users. Пример структуры базы:
CREATE TABLE `orders` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) DEFAULT NULL
)

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
)


И соответственно две модели:
class Order 
{

}

class User
{

}


Я хочу добавить в модель Order релейшен к User, например так:

...
public function getUser() 
{
    return $this->hasOne(User::className(), ['id' => 'user_id'];
}
...


но вот в этом месте есть одна важная особенность: модели Order и User (и соответственно таблицы, создаваемые с помощью миграций) находятся в разных модулях/расширениях. Причем, модуль для пользователей может быть заменен на другой (например, в другом проекте).

Соответственно, я не могу просто указать ссылку на User::className(), потому что имя класса и его неймспейс могут быть другими.

Таким образом, вопрос в следующем: как указать в методе getUser ссылку на класс User, который будет соответствовать текущему проекту?

Мои варианты
  1. В свойствах модуля для Order добавить свойство $userClass и прописывать туда имя класса
  2. Переопределять класс Order в некотором месте (например, в Bootstrap приложения) с помощью класса-наследника и уже в этом наследнике задавать relation, например:
    class OrderWithUser extends Order {
        public function getUser() 
        {
            return $this->hasOne(User::className(), ['id' => 'user_id'];
        }
    }
    
    // В bootstrap
    Yii::$container->set('namespace/to/Order', 'namespace/to/subclass/OrderWithUser')


  • Вопрос задан
  • 1294 просмотра
Решения вопроса 1
@maxyc_webber
Web-программист
return $this->hasOne(\app\module\admin\models\User::className(), ['id' => 'user_id'];
что мешает такое сделать?
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
@ewolf Автор вопроса
Мешает то, что модель \app\module\admin\models\User может быть заменена на другую, в другом модуле с другим неймспейсом. Общим между моделями может быть только то, что они:
a. Обе наследуются от ActiveRecord
b. Могут иметь некий общий интерфейс (например, UserInterface), который опишет обязательные для них всех методы (например, getFullName и т.п.).
Ответ написан
Комментировать
Terminaft
@Terminaft
Храните класс юзера в параметрах, и оттуда его таскайте в getUser
Ответ написан
Комментировать
Zhuravljov
@Zhuravljov
php-программист
Используйте \yii\web\User::$identityClass

То есть, в модели модуля ваша связь будет выглядеть так:
public function getUser()
{
    return $this->hasOne(Yii::$app->user->identityClass, ['id' => 'user_id']);
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы