Задать вопрос

Yii2 best practics. Как правильно организовать наследование моделей?

Есть проект на Yii2 фреймворке с шаблоном advanced. По гайду рекомендуют общую бизнес-логику моделей хранить в common, а специфичную логику реализовывать в соответствующий отнаследованных моделях frontend и backend.
Но что делать с отношениями? Получается их тоже надо обязательно переопределять? Приведу пример.

Модели пользователя и заказа в common:
namespace app\common\models;


use yii\db\ActiveRecord;

class User extends ActiveRecord{

    public function getOrder(){
        return $this->hasOne(app\common\models\Order::className(), ['user_id' => 'id']);
    }
}

namespace app\common\models;


use yii\db\ActiveRecord;

class Order extends ActiveRecord{

}


В frontend создаем классы унаследованный от соответствующих классов из common:
namespace app\frontend\models;


use yii\db\ActiveRecord;

class User extends app\common\models\User{

}

namespace app\frontend\models;

use yii\db\ActiveRecord;

class Order extends app\common\models\Order
{
    public function newMethod()
    {
           //Some logic
    }
}


И пробуем сделать так:

$user = new app\frontend\models\User();
$user->order->newMethod();


Схватим исключение, т.к. newMethod определен только в классе Order фронтенда.
Что же это получается? Определять отношения надо только в backend и frontend? А для чего тогда common нужен?
  • Вопрос задан
  • 1544 просмотра
Подписаться 5 Оценить Комментировать
Решения вопроса 1
SamDark
@SamDark
Yii2 core team
AR-класс в backend / frontend может не наследоваться от AR-класса из common, если логика их использования различна, пусть и немного схожа.

common нужен если у нас на уровне базы всё одинаково, а вот часть бизнес логики, заложенная прямо в AR-класс разная.

По хорошему, кстати, бизнес логику надо выносить в отдельный слой, но так как ради двух строчек лепить его не хочется, пока её мало, она остаётся в AR-классах.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@Mylistryx
public function getOrder(){
// было
return $this->hasOne(app\common\models\Order::className(), ['user_id' => 'id']);
// стало
return $this->hasOne(Order::className(), ['user_id' => 'id']);
}
поскольку у них один неймспейс, то отработает и в common и в front/back. При этом будет брать рядомлежащий класс.
Единственный ньюанс, что файл Order должен присутствовать во всех приложениях (common,front,back).
Ответ написан
Ваш ответ на вопрос

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

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