Страница 5 из 6
Re: WithRelatedBehavior
Добавлено: 2012.11.18, 12:33
mlapko
Код теста абстрактный, но передаёт смысл
Код: Выделить всё
class FooBehavior
{
public function events()
{
return array(
'onAfterConstruct'=>'afterConstruct',
'onBeforeValidate'=>'beforeValidate',
'onAfterValidate'=>'afterValidate',
'onBeforeSave'=>'beforeSave',
'onAfterSave'=>'afterSave',
'onBeforeDelete'=>'beforeDelete',
'onAfterDelete'=>'afterDelete',
'onBeforeFind'=>'beforeFind',
'onAfterFind'=>'afterFind',
);
}
protected function afterConstruct($event) {}
protected function beforeValidate($event) {}
protected function afterValidate($event) {}
protected function beforeSave($event) {}
protected function afterSave($event) {}
protected function beforeDelete($event) {}
protected function afterDelete($event) {}
protected function beforeFind($event) {}
protected function afterFind($event) {}
public function attach()
{
$class = new ReflectionClass($this);
foreach ($this->events() as $event => $handler) {
if (!$class->getMethod($handler)->isProtected())
echo $handler;
}
}
}
class EmptyBehavior extends FooBehavior
{
public function events() { return array(); }
}
class GeneralBehavior extends FooBehavior {}
// EmptyBehavior
$start = microtime(true);
for ($i = 0; $i < 1000; ++$i) {
$object = new EmptyBehavior();
$object->attach();
}
echo microtime(true) - $start, '<br/>';
// GeneralBehavior
$start = microtime(true);
for ($i = 0; $i < 1000; ++$i) {
$object = new GeneralBehavior();
$object->attach();
}
echo microtime(true) - $start;
Re: WithRelatedBehavior
Добавлено: 2012.11.18, 16:04
creocoder
Это только аттач. При реальной вставке/чтении записей время, которое будет затрачено на аттач станет незначительным. На трекере проводились реальные практические тесты. Таким образом незначительная потеря в скорости в общей картине при аттаче (за возможность не думать о перекрытии events()) это вполне допустимо.
Re: WithRelatedBehavior
Добавлено: 2012.11.18, 20:58
slavcodev
creocoder писал(а):
creocoder, отнаследуйтесь от CBehavior, повысит производительность, в вашем behavior'е CActiveRecordBehavior не нужен.
Во первых это было бы идеологически неправильно, во вторых в версии 1.1.13 появится мой и mc-bear фикс расхода памяти поведениями. Поэтому уже не актуально.
Что это за идеология такая? Мне кажется тебя запутали названия классов. Но нет ничего запрещающего использовать cbehavior с активными записями. учитывая что не юзается ни одно стандартное событие.
Re: WithRelatedBehavior
Добавлено: 2012.11.19, 16:53
creocoder
Что это за идеология такая? Мне кажется тебя запутали названия классов. Но нет ничего запрещающего использовать cbehavior с активными записями. учитывая что не юзается ни одно стандартное событие.
Сегодня не юзается, завтра юзается. ИМХО все поведения которые работают с AR должны наследовать CActiveRecordBehavior. Отсутствие событий это НЕ КРИТЕРИЙ делать у класса другого родителя. Тем более в целях какой то экономии на спичках. А после фикса это вообще уже не актуально.
Re: WithRelatedBehavior
Добавлено: 2012.11.19, 17:03
slavcodev
creocoder писал(а):Сегодня не юзается, завтра юзается. ИМХО все поведения которые работают с AR должны наследовать CActiveRecordBehavior
Да ладно. Откуда такие выводы? Только потому что у СActiveRecord и CActiveRecordBehavior есть приставка у класса? Что помешает конкретно этому поведению, когда завтра будет юзатся ивенты, поменять родителя? Да и когда появится завтра другая логика, то и поведение будет уже другое.
ЗЫ: Я предпочитаю не назвать то что сделали с поведениями фиксом, скорее это хак. Для меня фикс - это когда проблему убирают, в данном случае просто придумали как ее обойти
Re: WithRelatedBehavior
Добавлено: 2012.11.19, 17:08
creocoder
Но нет ничего запрещающего использовать cbehavior с активными записями.
И что? Нет ничего запрещающего делать ещё много нехороших с точки зрения ООП вещей в Yii. С Zend философией я уверен, что юзер пытающийся так сделать получал бы exception с трехэтажным матом. Но у нас не Zend, совершенно другая философия по поводу обработки ошибок. Поэтому всё на совести разработчиков расширений и конечных пользователей. Но иногда, вот от таких предложений "сэкономить на спичках" я жалею, что у нас такая политика обработки ошибок.
Я предпочитаю не назвать то что сделали с поведениями фиксом, скорее это хак. Для меня фикс - это когда проблему убирают, в данном случае просто придумали как ее обойти
Проблему именно устранили, а не обошли.
Re: WithRelatedBehavior
Добавлено: 2013.01.05, 19:02
karpo518
creocoder Спасибо вам за расширение. С ним код обработки сложных форм сократился до приятного размера. Скажите, не планируете ли вы добавить в поведение подобный метод для инициализации? Было бы здорово передавать модели один массив для инициализации её и связанных моделей. Особенно изящно это решение может использоваться при обработке вложенных форм.
Re: WithRelatedBehavior
Добавлено: 2013.02.03, 19:56
saygo
Хороший Behavior, как раз искал нечто подобное, часть задачи решил. Теперь другая часть, может поможете.
Есть
Users{
contract_id (PK)
.............
}
и Ip{
id (PK)
user_id (contract_id из предыдущей таблицы)
ip
}
У одного юзера может быть несколько Ip (минимум 1)
в users _form добавил
$ips=CHtml::listData(Ip::model()->findAll('user_id=:user_id', array(':user_id' => $model->contract_id)), 'id', 'ip');
foreach($ips as $i=>$ip)
{
echo CHtml::TextField('ip['.$i.']',$ip);
}
echo CHtml::TextField('ip['.$i.']','');
Что выводит инпуты с существующими IP + 1 поле, если нужно добавить еще
Подскажите, что нужно поменять, чтобы на этих инпутах работала валидация из Ip (регулярка по правильности + unique(это между собой не обязательно, визуально видно дубликат при 1-3 IP)).
Правильно сформировать массив $_POST, который использовать потом в контроллере вместо
$ip1 = new Ip;
$ip1->ip = "192.168....";
$ip1->user_id = $model->contract_id;
$model->ip = array($ip1,$ip2....);
Re: WithRelatedBehavior
Добавлено: 2013.02.12, 23:36
alexanoid
непонятно, при помощи этого расширения можно делать только save новой модели или можно также сделать и update. Если да - то как ? Спасибо.
Re: WithRelatedBehavior
Добавлено: 2013.02.12, 23:47
slavcodev
а разве update это не частный случай save? ты вызываешь update? смысл?
Re: WithRelatedBehavior
Добавлено: 2013.02.13, 00:00
alexanoid
mc-bear писал(а):а разве update это не частный случай save? ты вызываешь update? смысл?
смысл в том, что я Java программист и например в одном из джавишных ORM под названием Hibernate используется три метода - save, update and saveOrUpdate()
По старой привычке я стал искать аналоги здесь и не нашел. Отсюда и возник данный вопрос.
Re: WithRelatedBehavior
Добавлено: 2013.02.13, 00:56
slavcodev
Если подсмотреть в API метода save, можно увидеть что фреймворк автоматически сделает insert для новых записей и update для старых. Поэтому insert и update редко используется по каким-то слишком частным задачам.
Re: WithRelatedBehavior
Добавлено: 2013.02.13, 01:46
alexanoid
mc-bear писал(а):Если подсмотреть в API метода save, можно увидеть что фреймворк автоматически сделает insert для новых записей и update для старых. Поэтому insert и update редко используется по каким-то слишком частным задачам.
а в чем была трудность реализовать базовый сценарий с удалением из базы данных отсутствующих потомков в модели при ее апдейте ? Зачем эту рутину на программиста перекладывать ? Фактически теперь приходится писать каждый раз код для этого в beforeSave..
Re: WithRelatedBehavior
Добавлено: 2013.02.13, 01:49
alexanoid
alexanoid писал(а):mc-bear писал(а):Если подсмотреть в API метода save, можно увидеть что фреймворк автоматически сделает insert для новых записей и update для старых. Поэтому insert и update редко используется по каким-то слишком частным задачам.
а в чем была трудность реализовать базовый сценарий с удалением из базы данных отсутствующих потомков в модели при ее апдейте ? Зачем эту рутину на программиста перекладывать ? Фактически теперь приходится писать каждый раз код для этого в beforeSave..
либо в таком случае можно было добавить дополнительным параметром сценарий требуемого поведения в метод save
Re: WithRelatedBehavior
Добавлено: 2013.04.10, 14:04
XAKEPEHOK
Похоже, что я где-то туплю, но не могу понять где. Есть 2 модели: Users и Advertisers, где Users HAS_ONE Advertisers, и соответственно, Advertisers BELONGS_TO Users
Код: Выделить всё
<?php
/**
* @property integer $userID
* ...
* The followings are the available model relations:
* @property Users $user
*/
class Users extends CActiveRecord
{
//... подключаю поведение
public function relations()
{
return array(
'advertiser' => array(self::HAS_ONE, 'Advertisers', 'userID'),
);
}
}
Код: Выделить всё
<?php
/**
* @property integer $id
* ...
* The followings are the available model relations:
* @property Advertisers $advertiser
*/
class Advertisers extends CActiveRecord
{
//... подключаю поведение
public function relations()
{
return array(
'user' => array(self::BELONGS_TO, 'Users', 'userID'),
);
}
}
В действии контроллера
Код: Выделить всё
$user = new Users('fromRequest');
$user->email = $advRequest->email;
$user->login = substr($advRequest->email,0,strpos($advRequest->email,'@'));
...
$user->advertiser = new Advertisers();
$user->advertiser->name = $advRequest->name;
$user->advertiser->phone = $advRequest->phone;
...
$user->withRelated->save(true,array('advertiser'));
В общем, при попытке сохранить получаю:
Не определено свойство "Users.userID". - связи вроде указаны правильно. Ни в событиях моделей, ни в контроллере обращений к Users.userID нет.
Вылетает следующий exception:
C:\WebServer\domains\onelead\protected\extensions\wr\WithRelatedBehavior.php(239): CActiveRecord->__get("userID")
Код: Выделить всё
234 switch($relationClass)
235 {
236 case CActiveRecord::HAS_ONE:
237 $map = $this->getDependencyAttributes($fks, $ownerTableSchema, $relatedTableSchema);
238 foreach ($map as $fk => $pk) {
239 $related->$fk = $owner->$pk; // <<--- выделена эта срока
240 }
241
242 if($data===null)
243 $related->getIsNewRecord() ? $related->insert() : $related->update();
244 else
Re: WithRelatedBehavior
Добавлено: 2013.04.10, 14:22
XAKEPEHOK
Извиняюсь, действительно мой косяк. У меня в модели advertisers поле userID было как PRIMARY, а не как INDEX. Проблема решена
Re: WithRelatedBehavior
Добавлено: 2013.04.25, 16:09
Adept
Подскажите, как лучше всего решить ситуацию:
таблицы post, tag
связаны через posts_to_tags
tag_name - уникальный индекс
Надо чтобы при сохранении поста создавалось соответствие с тегом в таблице связей, но сами теги сохранялись только, если уникальные.
Сейчас при сохраненни тегов, мускул выдает ошибку если тег есть уже. Надо как то реализовать on duplicate key ignore для тегов.
Re: WithRelatedBehavior
Добавлено: 2013.04.25, 16:33
XAKEPEHOK
Попробуйте посмотреть в сторону
taggable-behavior
Re: WithRelatedBehavior
Добавлено: 2013.04.25, 17:33
Adept
Я просто думал что это расширение реализует сохранение в таблицы со связями многие к многим, а сейчас идет попытка создать дубликат в поле тег и выходит что 1 полю пост соответствует несколько тегов, но одной записы таблицы тегов соответствует 1 пост, т.е. 1 к моногим.
Re: WithRelatedBehavior
Добавлено: 2013.04.25, 22:14
Adept
XAKEPEHOK, спасибо! Эта штука работает как надо)