Основы ORM — Изменение записей

Комментарии: 15  Просмотры: 22 386

В прошлом уроке мы рассмотрели выборку данных из базы посредством ORM. Естественно возможности ORM на этом не ограничиваются и мы также просто можем добавлять, изменять и удалять записи.
Добавление делается следующим образом:

$category = ORM::factory('category');
$category->name = 'Спички';
$category->description = 'Все о спичках';
$category->save();

Данный код добавит в таблицу категорий новую запись с заполненными полями name и description. Само добавление происходит после вызова метода save(). Этот же код можно переписать несколькими альтернативными способами, сделать его более компактным. Например, таким:

ORM::factory('category')
        ->set('name', 'Спички')
        ->set('description', 'Все о спичках')
        ->save();

Или даже таким:

$data = array('name' => 'Спички', 'description' => 'Все о спичках');
 
ORM::factory('category')
        ->values($data)
        ->save();

Этот вариант очень удобен при сохранении данных с отправленной формы. Вместо $data будет $_POST и конечно же поля формы должны называться также, как поля таблицы, куда мы вставляем данные. Все способы можно использовать в совокупности:

$data = array('name' => 'Спички', 'description' => 'Все о спичках');
 
$category = ORM::factory('category')
            ->set('keywords', 'спички, поджигать')
            ->values($data);
 
$category->alt_name = 'matches';
$category->save();

Изменение записей делается совершенно аналогично. Отличие лишь в том, что мы сначала должны выбрать изменяемую запись. Например, изменим запись с идентификатором 27:

$data = array('name' => 'Пакля', 'description' => 'Все о пакле');
 
ORM::factory('category', 27)
        ->values($data)->save();

Чтобы изменить несколько записей, нужно пройтись по ним в цикле, изменяя каждую запись. Поменяем всю «Паклю» на «Рваклю»:

$categories = ORM::factory('category')
            ->where('name', '=', 'Пакля')
            ->find_all();
 
foreach($categories as $category)
{
    $category->set('name', 'Рвакля')->save();
}

Но вот цикл — это не очень хорошо и в таких случях я все-таки использую DB::update, шустрее работает. Если есть какой-то способ изменения нескольких записей без использования цикла, пожалуйста, отпишите в комментариях.
Идем дальше. Как вы заметили, метод save() используется и для добавления, и для изменения записи. Тут таится некая опасность. Если мы захотим поменять запись, но при выборке она не будет найдена, то вместо этого будет создана новая запись. Можно использовать метод loaded() для проверки, но все равно с методом save() постоянно возникает путаница. Видимо также подумали создатели Коханы и начиная с версии 3.1 ввели методы create() и update(), оставив save() для обратной совместимости. Я настоятельно рекомендую использовать эти два метода вместо save(). При попытке обновить несуществующую запись мы получим ошибку.
Для удаления записи используется метод delete(). Удалим запись с идентификатором 27:

ORM::factory('category', 27)
        ->delete();

Для удаления нескольких записей опять используем цикл. В старых версиях Коханы вроде как существовал метод delete_all() для массового удаления, по крайней мере в литературе я встречал о нем упоминания. Но в 3.2 похоже убрали.

И напоследок еще один полезный метод, который позволяет посчитать количество записей:

$categories = ORM::factory('category')
             ->where('parent_id', '=', 7);
 
echo $categories->count_all();

Мы получим количество записей, у которых parent_id равен 7. На этом закончим с основами. В следующем уроке мы перейдем к очень важной теме — связям между таблицами. ORM настолько упрощает работу со связанными таблицами, что потом просто не представляешь, как раньше без этого обходиться. Это действительно очень удобно.

<< Назад | Вперед >> | Обсудить на форуме


К записи оставлено 15 коммент.

хм..как вы будите менять запись если ее не будет?
смотрим -> =)

$a = ORM::factory(‘call’)->where(‘id’,'=’,$page)->where(‘userid’,'=’,$this->user->id)->find();
$a->values($_POST);
$a->save();
$this->request->redirect(url::site(‘sozvon/my’));

…суем все в try()catch() и ловим исключения и все =)

Знаете, тут ситуация как с глобальным массивом $_REQUEST. Никогда не приходилось им пользоваться, потому что я всегда знаю, где у меня лежат данные.
Так и тут…если вы обновляете (добавляете) запись, зачем использовать именно save ? Для путаницы ?
Бывают ситуации, когда в случае отсутствия записи ее нужно создать. Тогда да — удобно. А в других случаях…
Имхо.

причем тут » глобальным массивом $_REQUEST» ? (там просто редирект)

я вам писал про ЭТО
$q=ORM::factory(‘call’)->where(‘id’,’=’,какая запись)->where(‘userid’,’=’,проверяем авторство)->find()
try{
$q->save($_POST);
}catch(ORM_Validation_Exception $e){
$errors=$e->errors(‘models’);
}
и все )) если ненайдено в таблице записи или не ваша запись то вы получаете исключение — ошибку и формируемете (в message). ВЫ полюбому не создатие НОВУЮ запись так как запрос у вас с условием

могу подсказать (romawka_ural(гав)mail.ру) в агент =)

Ну. А еще можно loaded() использовать.

он покажет вам загружен ли обьект а когда валидацию проганять?

находим проверяем авторство и обновляем запись .. так что все с save() ОК! используйте

Да кстати, вдогонку. Если нам надо добавить запись, а не обновить… В гвайде по кохане Джейсона Страугхана видел такие варианты.
Генерация исключения при попытке обновить запись вместо создания:

public function create(array $data)
{
    if(!$this->empty_pk() && !isset($this->_changed[$this->_primary_key]))
    {
        throw new Exception('Cannot create new message, 
object contains a loaded message already')
    }
    $this->values($data);
    $this->save();
}

Исключение исключением, но если предварительно очистить объект:

public function create(array $data)
{
    $this->clear();
    $this->values($data);
    $this->save();
}

Полагаю, что этот вариант и используется при вызове метода create в 3.2. Лень щас что-то смотреть исходники :)

А вот и свежий урок :)

По поводу delete_all() я в форуме отписался

Да видели видели уже. Оно самое с циклом. Увы.

А такая конструкция для удаления не пойдет?

Код:

ORM::factory(‘category’)
->where(‘name’, ‘=’, »Тапки’)
->delete();

Возможно ли реализовать добавление нескольких записей в таблицу одним запросом с помощью ORM?
В частности необходимо перенести содержимое файла .csv в базу (число строк ~40000).
Если нет возможности то что целесообразнее использовать: цикл ORM, либо методы Database?

методы Database.
Кто-то уже кстати интересовался на форуме подобным вопросом

Мне нужно изменить(обновить) запись в БД. При помощи save() не получается, в место изменения записи добавляется новая. Я делаю форму редактирования. В общем суть в том что нужно в адресной строке ввести id записи и затем содержимое записи загружается в определенные поля формы, содержимое полей нужно изменить и сохранить. Все проходит нормально но только запись не обновляется а просто добавляется новая. В начале метода использую вот это:

$parameters = $this->request->param();

Потом еще код для вывода записей из таблицы в поля формы и валидация. А вот сам отрывок кода для изменения записи:

$city = ORM::factory(‘city’, $parameters['id']);
$city->name = $_POST['name'];
$city->about = $_POST['description'];
$city->save();
if($city->saved())
echo ‘город ‘.$city->name.’ сохранен’;

Не пойму в чем дело…



Оставить комментарий или два

Пожалуйста, зарегистрируйтесь для комментирования.