Как реализовать в Yii2 создание одной модели ActiveRecord на основании другой модели ActiveRecord?
Как динамически подтянуть свойства одной модели в другую ?
Существует основная модель ActiveRecord которая называется HUMAN ('Люди') , она содержит такие данные как ФИО, контактные данные и прочее. class Human extends ActiveRecord
Для удобства предположим что в ней всего 3 свойства ( ID, NAME, CONTACT)
И есть модели учителей ( TEACHER ) и учеников( PUPIL ) расширяющие свойства модели HUMAN, а именно содержат свойства специфические либо только для учителей , либо только для учеников соответственно .
И объявляется так: class Teacher extends Human
Для удобства предположим что TEACHER имеет только 3 поля свойст , которые берутся из одноименной таблици, а именно (ID ,HUMAN_ID, PREDMET)
ID - ID в таблице учетелей
HUMAN_ID - ссылка на ID в таблице HUMAN
PREDMET - название предмета которые ведет данный учитель
Таким образом я можно сказать объединяю 2 модели в одну для удобства , а логика распределения по таблицам реализуется в таких методах как BeforeSave.
Однако что бы данная схема работала, приходится принудительно прописывать свойства модели HUMAN в модели TEACHER, почему-то они не наследуются . (в таблице TEACHER прописываю public $NAME; public CONTACT;)
Вопрос , как сделать что бы свойства модели HUMAN , наследовались или переносились в модель TEACHER , без принудительного перечисления, поскольку , если расширить свойства модели HUMAN прийдется вносить изменения и в TEACHER.
Код модели TEACHER:
<?php
namespace common\models;
use Yii;
class Teacher extends Human
{
// Как подтянуть эти свойства ДИНАМИЧЕСКИ с модели HUMAN и почему они не наследуются?
// ----------------------------
public $NAME;
public $CONTACT;
// ----------------------------
public function getHuman0()
{
return $this->hasOne(Human::className(), ['ID' => 'HUMAN_ID']);
}
public function beforeSave($insert)
{
if (parent::beforeSave($insert)) {
if($this->isNewRecord){
// если мы создаем нового пользователя, тогда нам необходимо создать
// для него запись в таблице профиля с ссылкой на родительскую таблицу
$human = new Human;
$human->NAME = $this->NAME;
$ok=$human->save();
$this->HUMAN_ID=$human->ID;
if (!$ok) return false;
} else
{
if (($human = Human::findOne($this->HUMAN_ID)) !== null) {
$human->NAME=$this->NAME;
$ok=$human->save();
if (!$ok) return false; }
}
return true;
}
return false;
}
public function afterDelete()
{
parent::afterDelete();
if (($human = Human::findOne($this->HUMAN_ID)) !== null) {
$ok= $human->delete();
if (!$ok) return false; }
return true;
}
}
Модель HUMAN :
<?php
namespace common\models;
use Yii;
class Human extends \yii\db\ActiveRecord
public static function tableName()
{
return 'HUMAN';
}
public function rules()
{
return [
[[ 'NAME'], 'required'],
[['NAME', 'CONTACT'], 'string', 'max' => 200],
];
}
public function attributeLabels()
{
return [
'ID' => Yii::t('app', 'ID'),
'NAME' => Yii::t('app', 'Name'),
'CONTACT' => Yii::t('app', 'Contact'),
вот это Вы намудрили... У Вас абсолютно не верная концепция. Во первых зачем Вам базовая модель Human? судя по его смыслу это вообще избыточный класс. Но даже если предположить что она зачем-то нужна то судя по структуре базы данных у Вас данные организованы в виде реляций, а работаете Вы с ними через наследования.
Объясняю почему именно через наследование: модель HUMAN сделана для того , что бы не хранить общие поля такие как (NAME,CONTACT.....), тобто не дублировать эти поля в табляцах УЧИТЕЛЕЙ, УЧЕНИКОВ, РОДИТЕЛЕЙ, а хранить только ссылку. Одной записи в таблице HUMAN , может соответствовать только одна запись из таблицы Учеников( связь hasOne) , поэтому это как расширение свойств ОБЪЕКТА, мы как бы дополняем объект другими свойствами специфическими только либо учителям , либо ученикам, либо родителям.
Делается это для того что бы вся логика (добавления,удаления...., в связаных таблицах) была реализована не на уровне контролера , а на уровне модели.
Более того предложенный вариант рабочий, хотя возможно многие в нем не видят логики, предпочитая реализовать все на уровне контролера.
Но основной вопрос именно в том как подтягивать свойства объекта HUMAN в объект TEACHER динамически , а не прописывать их принудительно?
Две таблицы, две модели доступ к данным через relations
Зачем городить еще что-то?
Если кроме учителей еще есть типы людей, создаете еще модели, а в таблице ЛЮДИ делаете доп поле "тип" и в моделе ЛЮДИ функцию getData, которая возвращает данные из тои или иной связи в зависимости от типа.