Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Удаление связанных данных необходимо реализовать в beforeDelete() обработчике.
User::model()->withFlags(User::FLAG_CONFIRM_EMAIL)->findAll();const FLAG_CONFIRM_EMAIL = 1; // 00000001
const FLAG_CONFIRM_PHONE = 2; // 00000010
const FLAG_BEST_AUTHOR = 4; // 00000100
...
/**
* Устанавливает флаг
* @param integer $flag
* @return \User
*/
public function setFlag($flag)
{
$this->flag += intval($flag);
return $this;
}
...
$user->setFlag(User::FLAG_CONFIRM_EMAIL);
$user->setFlag(User::FLAG_CONFIRM_EMAIL);
$user->hasFlag(User::FLAG_CONFIRM_PHONE); // == true (внезапно)
unsetFlag(...))$this->flag |= intval($flag);$this->flag &= ~intval($flag);Модели предназначены только для оперирования данными (поиск, сохранение, удаление)
if ($model->status !== 1 && $model->status !== 2 && $model->status !== 4) { }
if (!in_array($model->status, [1,2,4])) { }
true третьим параметром.if (array_key_exist($model->status, [1=>0, 2=>0, 4=>0])) {}
/**
* @property string statusTitle
*/
class MyModel extend CActive Record{
const STATUS_CREATED = 1;
const STATUS_SENT = 2;
public static $statusTitles = array(
self::STATUS_CREATED => 'Новый',
self::STATUS_SENT => 'Отправленный',
);
public function getTypeTitle() {
return self::$statusTitles[$this->status];
}
public function getTypeTitleDesigned() {
return self::$statusTitles[$this->status];
}
/**
* для определенных случаев выводим "разукрашенную" версию статуса.
*/
public function getStatusTitleDesigned() {
// по своей логике определяем украшения: скажем, иконку и цвет в стиле Twitter Bootstrap'a
$color = 'success';
$icon = 'ok';
return TbHtml::labelTb(TbHtml::icon($icon) . " " . $this->statusTitle, array(
'color' => $color,
));
}
}
}/**
* @property Member[] $members
*/
class MyModel extend CActive Record{
public function rules() {
return array(
//....
array('newMembers', 'safe'), // для того чтобы можно было получить данные из формы
array('newMembers', 'validateData'), // для их валидации
//....
);
}
public function relations() {
return array(
//....
'members' => array(self::HAS_MANY, 'Member', 'teamId', 'index' => 'id'),
//....
);
}
/**
* Получение из формы табличных данных и объединение их с уже существующими.
* @param mixed $newMembers
*/
public function setNewMembers($newMembers) {
$members= $this->members;
foreach ($newMembers as $memberId=> $data) {
if (is_numeric($memberId) && $memberId!= 0) { // отсекаем ненужные данные
if ($members[$memberId]) { // если уже существует
$member= $members[$memberId];
} else { // если не находим, создаем новую модель
$member= new Member('create');
$member->teamId= $this->id;
$members[$memberId] = $member;
}
$member->team= $this; // для того чтобы избегать лишних запросов к базе
$member->attributes= $data;
};
}
$this->rates = $rates; // вся магия здесь =)
}
}
/**
* Проверка данных
*/
public function validateData() {
if (!$this->rates) return true;
$ok = true;
foreach ($this->rates as $rate) {
$ok = $rate->validate() && $ok;
}
return $ok;
}
/**
* Сохранение данных
*/
protected function afterSave() {
$this->saveData();
parent::afterSave();
}
public function saveData() {
if (!$this->members) return;
foreach ($this->members as $member) {
$member->save(false); // мы данные уже проверили в validateData()
}
}
class TeamController extends Controller{
/**
* Добавление нового команды и ее членов
*/
public function actionCreate() {
$model = new Team('create');
if (isset($_POST['Team'])) {
$model->attributes = $_POST['Team'];
$model->setNewMembers($_POST['Member']);
/*
Подразумевается, что в представлении в одной форме мы
вместе заполняем данные и для команды и для ее членов.
Хотя и здесь, конечно, можно выпендриться и добавлять все данные о членах команды
в том же массиве, что и команда.
Таким образом сократиться второе присваивание, только можно будет запутаться в именах. =)
*/
if ($model->save()){
Yii::app()->user->setFlash('success', 'Все замечательно');
$this->redirect(array('view', 'teamId' => $model->id));
}else{
Yii::app()->user->setFlash('alert', 'Возникли ошибки');
}
}
$this->render('create', array(
'model' => $model,
));
}
}
const STATUS_CREATED = 'created'; В коде без разницы, в БД относительно небольшая разница.Чуть меньше не понравилась идея задавать символьные обозначения константам на естественном языке.
если создавать для отображения каждого поля отдельный виджет и хелпер в котором будет один метод с объемом в пару строк, то вы просто потонете в файлах
Вы говорили об массиве $statusTitles? Это не обозначения констант, а расшифровка из значений.
Yii обмен опытом: модели (окончание)