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 нужен?
  • Вопрос задан
  • 1536 просмотров
Решения вопроса 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).
Ответ написан
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы