Связывания нескольких моделей через метод link

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
edvardpotter
Сообщения: 26
Зарегистрирован: 2017.08.19, 21:40

Связывания нескольких моделей через метод link

Сообщение edvardpotter » 2017.10.20, 12:10

Здравствуйте.
При регистрации пользователя создается модель Shop, у этой модели в методе afterSave, создается модель User:

Код: Выделить всё

public function afterSave($insert, $changedAttributes)
    {
        parent::afterSave($insert, $changedAttributes);
        $user = new User();
        $user->shop = $this;
        $user->name = $this->email;
        $user->save();
    }
А у User в свою очередь тоже в методе aftetSave создается модель Kassir:

Код: Выделить всё

public function afterSave($insert, $changedAttributes)
{
        parent::afterSave($insert, $changedAttributes); // TODO: Change the autogenerated stub
        $kassir             = new Kassir();
        $kassir->login      = $this->name;
        $kassir->pass       = md5(uniqid(rand(), true));
        $kassir->is_main    = 1;        
        $kassir->link('shop', $this->shop);
        $kassir->link('user', $this);
        $kassir->save();
}
При регистрации выкидывает исключение:
exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`nekarta`.`kassir`, CONSTRAINT `kassir_ibfk_2` FOREIGN KEY (`uid`) REFERENCES `user` (`id`))'
По ошибке понятно что второй link по какой-то причине не устанавливается, смотрю в логах и вижу следующее:
INSERT INTO `kassir` (`login`, `pass`, `is_main`, `sid`) VALUES ('test@test.ru', '7cb8795fcdbad118c2ef7947250931ab', 1, 12)
Т.е. uid не передается, если поменять линки местами то тогда uid устанавливается, а sid нет. Но если устанавливать id вручную:

Код: Выделить всё

$kassir->sid = $this->shop->id;
$kassir->uid = $this->id;
То все добавляется и работает нормально.
Поэтому вопрос, почему нельзя использовать несколько link?

Аватара пользователя
yiijeka
Сообщения: 2965
Зарегистрирован: 2012.01.28, 09:14
Откуда: Беларусь

Re: Связывания нескольких моделей через метод link

Сообщение yiijeka » 2017.10.20, 12:23

Не вижу в ваших afterSave логику uid и sid...

edvardpotter
Сообщения: 26
Зарегистрирован: 2017.08.19, 21:40

Re: Связывания нескольких моделей через метод link

Сообщение edvardpotter » 2017.10.20, 12:34

yiijeka писал(а):
2017.10.20, 12:23
Не вижу в ваших afterSave логику uid и sid...
https://pastebin.com/Yevt2s74 если вы об этом

someweb
Сообщения: 288
Зарегистрирован: 2017.03.09, 10:12

Re: Связывания нескольких моделей через метод link

Сообщение someweb » 2017.10.20, 12:57

Ну так link же сохраняет модель. А когда вызывается первый link, второе поле пустое.
Кстати, а нормально, что при любом изменении модели Shop будут создаваться новые User и Kassir?

edvardpotter
Сообщения: 26
Зарегистрирован: 2017.08.19, 21:40

Re: Связывания нескольких моделей через метод link

Сообщение edvardpotter » 2017.10.20, 13:26

someweb писал(а):
2017.10.20, 12:57
Ну так link же сохраняет модель. А когда вызывается первый link, второе поле пустое.
Т.е. когда вызывается link, сохраняется модель kassir?
Кстати, а нормально, что при любом изменении модели Shop будут создаваться новые User и Kassir?
Нет, не нормально, я пока не добавил проверку на редактирование модели.

Аватара пользователя
yiijeka
Сообщения: 2965
Зарегистрирован: 2012.01.28, 09:14
Откуда: Беларусь

Re: Связывания нескольких моделей через метод link

Сообщение yiijeka » 2017.10.20, 13:36

Если не нормально, то от использование afterSave нужно отказаться. Вообще на моей практике использовать afterSave приходится очень редко.

Всю логику создания вашего Shop нужно держать в одном месте, а не в разных ActiveRecordах.

edvardpotter
Сообщения: 26
Зарегистрирован: 2017.08.19, 21:40

Re: Связывания нескольких моделей через метод link

Сообщение edvardpotter » 2017.10.20, 13:57

yiijeka писал(а):
2017.10.20, 13:36
Если не нормально, то от использование afterSave нужно отказаться. Вообще на моей практике использовать afterSave приходится очень редко.

Всю логику создания вашего Shop нужно держать в одном месте, а не в разных ActiveRecordах.
Такой вариант пришлось сделать потому что user создается при регистрации пользователи или при ручном создании kassir.

someweb
Сообщения: 288
Зарегистрирован: 2017.03.09, 10:12

Re: Связывания нескольких моделей через метод link

Сообщение someweb » 2017.10.20, 14:44

link(): The method will modify the values of the attributes that link two Active Record instances and save them to the database.

Сделайте класс, который будет создавать user с нужными параметрами и вызывайте где нужно.
Класс ActiveRcord не должен быть ответственным за создание других объектов.

Ответить