Pull to refresh

Comments 10

Честно говоря, мне не кажется, что такое применение очевидно. В смысле, взглянув на код
if ($client->save()) {
         foreach ($contacts as $contact) {
               $contact->clientId = $client->primaryKey;
               $contact->save();
         }
   }

Сразу же понятно, что он делает.

А посмотрев на ваше решение…

Имхо, если уж сохраняете связанные данные, то и нужно расширять саму модель. То есть, без вот такого:
$order = new Order;
$address = new Address;
$user = new User;
$contacts = array(new Contact);
$invoice = new Invoice;

А, например, как-то так:
$invoice = new Invoice;
$invoice->addContactInfo($info); // if we have many contacts per client
$invoice->address = $address; // if we have only 1 address per client
$invoice->save();
Хотя, скорее, в рамках Yii это должно быть как-то так:
$invoice = new Invoice;
$invoice->address = $address; // if we have only 1 address per client
if ($invoice->save())
    $invoice->addContactInfo($info); // if we have many contacts per client
Ну и, в Yii для подобных вещей вполне можно применять afterSave(). Думаю, ваш behavior как раз его и использует. Так, может, лучше конфигурировать этот самый behavior в основной модели? И вызывать самый обыкновенный save() безо всяких премудростей?
Дело еще в том, что afterSave не вызовется, если сам Save не был успешен. В таком случае валидация остальных моделей даже не начнется, и получиться ступенчатая проверка формы на ошибки, — сначала invoice, потом contact и т.д. Хотелось бы, проверить все модели сразу, и рассказать об ошибках пользователю. Для этого придется писать код для предварительной валидации всего, а затем, если не было ошибок, то сохранения. Трансакции + одновременное сохранение позволяет этого избежать.
Ну можно же проверять и на клиенте? В Yii есть виджет, позволяющий делать проверку на клиенте. Легко конфигурируемый :)
Просто, в вашем случае в любом случае придется подключать сам behavior к нужной модели, а потом писать кучу скопипащенного кода (->saveWith(), ->relationalSave()). Плюс, как вы верно подметили, можно переопределить методы валидации и сделать, чтобы валидация происходила сразу же, а не ступенчато.
Расширение ваше, решать вам, как ему лучше будет :)
Да, так наглядней, не спорю, но так для каждой новой модели, которую нужно сохранять, нужно менять модель, дописывать «address» и «addContactInfo», и другое. В моем варианте, имеется возможность сохранять любые модели, устанавливая связи между ними, при этом не меняя сами модели.
Не-не-не :) Я просто предлагаю как-то это сделать более читабельным в самом коде. Прочитайте, пожалуйста, мой комментарий выше. Т.е. мой третий коммент в цепочке.
Почему вы считаете что saveWith и relationalSave не читабельно?
А этот код:
$order = new Order;
$address = new Address;
$user = new User;
$contacts = array(new Contact);
$invoice = new Invoice;


Собственно, не является частью решениея и эти данные (модели) можно получать откуда угодно — из других компонентов или relations, например, в любом виде.
Просто стандартные методы Yii уже воспринимаются легко. Ну, например:
$client = new Client;
$client->attributes = Yii::app()->request->getQuery($key);
$client->save();

Ну и, мне просто всегда казалось, что когда модель сама отвечает за сохранение связанных данных — это хорошо. Ибо тогда не надо будет каждый раз в контроллерах писать один и тот же код.
Давно хочется в yii что-то типа рельсковских validates_associated и accepts_nested_attributes_for, а то какие то костыли нечитабельные =(
Sign up to leave a comment.

Articles