Для работы со штатным ORM нужно заводить модель для каждой таблицы. Всегда. Она может быть вообще пустой, но она должна быть. Ну, необязательно совсем пустой, там могут быть описания связей и всё такое.
Но всё выше сказанное не означает, что больше в моделях писать нечего. Ниже я попытаюсь систематизировать, что ещё такого можно, и даже стоит написать именно в модели.
1. Перечень полей
=========================
В модели обязательно должны быть описаны все поля таблицы. Подробнее проблема описана тут
Это должно выглядеть примерно так:
protected $_table_columns = array( ‘id’ => array(‘type’=>’int’), ‘title’ => array(‘type’=>’string’), ‘slug’ => array(‘type’=>’string’), ‘opened’ => array(‘type’=>’int’), ‘start_date’ => array(‘type’=>’date’), ‘end_date’ => array(‘type’=>’date’) );
Понятно, что в каждом случае набор полей может отличаться.
Если структура полей ещё будет меняться — наверное не стоит торопится с этим списком.
2. Характерные для этой таблицы фильтры
=========================
Представьте себе что периодически нужно делать одну и ту же проверку для записей этой таблицы. Можно, конечно, каждый раз писать новое where, но лучше сделать для этого метод в модели. Даже если там будет всего одна строчка, поверьте, читаемость и писаемость лёгкость написания заметно увеличится!
Пример такой функции:
public function published_only() { $this-> where(‘is_draft’, ‘=’, ‘0’); return $this; }
и всё. В следующий раз вам не стоит париться и вспоминать какие поля и чему там они должны быть равны. Вам останется только логика приложения.
3. Характерное для этой таблицы представление данных
===============================
Иногда в базе данных удобно хранить одно, но показывать удобно другое. Примеры? Пожалуйста!
Храним в базе данных таймштамп, а порой нужно отображать отдельно дату и отдельно время:
public function get_date(){ return substr($this->date, 0, 10); } public function get_time(){ return trim(substr($this->date, 10)); }
Или ещё вот, храним в базе данных длину в дюймах, но можем вывести её раздельно в футах и дюймах:
function length_ft(){ return floor($this->length/12); } function length_in(){ return $this->length- floor($this->length/12)*12; }
А вот ещё, xраним в базе данных полные имя и фамилию, а можем вывести фамилию и инициалы:
function get_name(){ return $this->get(«name») ? $this->first_name.» «.$this->last_name : $this->first_name.» «.substr($this->last_name,0,1). ($this->last_name?».»:»»); }
И таких примеров можно придумать много. Кто-то наверное подумает, что не стоит заводить функцию на пару строк, и лучше каждый раз писать этот код. Чтож, каждый решает для себя.
4. Нестандартная обработка данных
============================
Например, выполняется голосование. Пользователь сайта ткнул на оценку (сердечко, звёздочку), и теперь нужно пересчитать средний голос. Для этого очень удобно добавлять оценки прямо в таблицу того за что голосуют (посты, видео, фото и т.д.), а раз данные прямо в таблице — то давайте сделаем метод для их подновления:
public function vote($mark){ $this->rate= ($this->rate_count*$this->rate_count + $mark) /($this->rate_count+1); $this->rate_count++; $this->save(); }
Да мало ли что вообще можно сделать!
Нестандартная обработка при сохранении
============================
Если при сохранении записи кроме собственно сохранения производится ещё серия действий над данными, например заполнить их значениями по-умолчанию, то можно хакнуть save() запихнуть прямо туда все эти дела:
public function save(){ if ($this->title==») $this->title=’Untitled’; parent::save(); }
Единственное пожелание, если вам слишком понравилось туда всё пихать — то очень скоро ваш save() может превратиться в помойку. Старайтесь писать читабельно и, по-возможности, выносить код в отдельные методы.
Валидация
============================
Обязательно используйте валидацию! Обязательно используйте валидацию встроенную в ORM. Если привыкнете так делать, то это существенно продвинет ваш код. Правила и поля для валидации стоит прописывать прямо в модели, а проверять просто вызовом метода check(). Что-то на подобие этого:
if ($my_model->check() { $my_model->save(); }else{ $data[‘errors’]= $my_model->validate()->errors(«»); $data[‘data’]= $my_model; $this->template->content = new View(«editform», $data); }
Если у вас есть своя хитрая проверка при сохранении, которая не вписывается по каким-нибудь причинам в логику штатных средств валидации — стоит впихнуть их туда силой.
Например можно сделать хак метода check() по той же схеме. При этом удобно, чтобы ваш текст ошибки вписался в штатный массив ошибок. Например так:
if(ваше_условие){ $this->_validate->error(‘Название_поля_с_ошибкой’,’Индекс_ошибки’); $result=false; }
Понятно, что сам текст ошибки нужно прописать в /application/messages/validation.php. Следует обратить внимание на индекс кода ошибки.
Вместо резюме
============================
Описывая всё вышесказанное одним предложением , можно сказать так, что следует максимально отделять логику поведения данных от логики приложения. Зачем? Просто мелкие куски легче разжевать и проглотить. Удачи всем!
=)