Дек 10 2008
Мягкое удаление с помощью Soft Delete Behavior
С помощью этого компонента вы можете использовать в своих проектах «мягкое удаление» - т.е. установку флага для пометки удаленных записей, вместо реального их удаления. Зачем это нужно? Например, для хранения предыдущих версий отредактированных записей на блоге, для сохранения архива старых товаров в магазине — применений масса. Я стараюсь во всех своих проектах использовать «мягкое удаление» даже просто для того чтобы исключить ошибку случайного удаления. Заказчики часто обращаются: «ой, а мы удалили, а потом передумали, а можно восстановить?».
Внимание! Я еще не тестировал этот компонент с CakePHP 1.2 RC3. Судя по отзывам в комментариях к компоненту, есть проблемы с совместимостью. Эта запись — перевод документации, в следующей я опишу возможные проблемы и пути их решения.
1. Установка.
Создайте файл soft_deletable.php в папке /app/models/behaviors/.
Для тех моделей, в которых будет применяться «мягкое удаление» создайте специальное поле для хранения флага удаления, например deleted. Значение этого поля будет выставляться в 1 при «удалении» записи. Также, вы можете создать дополнительное поле для хранения времени удаления, например deleted_date.
2. Использование
Самый простой способ подключения этого компонента к вашему приложению, это добавление его названия в массив $actsAs. Например, у вас есть модель Article, привязанная к таблице articles (и в таблице уже созданы поля deleted и deleted_date). Отредактируйте файл модели /app/models/article.php и добавьте в него $actsAs:
<?php class Article extends AppModel { var $name = 'Article'; var $actsAs = array('SoftDeletable'); } ?>
И, в общем то, все. Теперь, когда вы используете функцию del(), запись будет удалена «мягко» - поле deleted станет единичкой, а в deleted_date запишется timestamp.
Чтобы изменить настройки компонента, надо добавить массив с новыми настройками к $actsAs. Вы можете изменять следующие настройки:
- field: имя поля для хранения флага удаления. Можно сделать булевым (или integer(1)). Значением по-умолчанию у поля должен быть 0. При удалении устанавливается в 1. Имя поля по-умолчанию — deleted.
- field_date: имя поля для хранения времени удаления записи. По-умолчанию — deleted_date. Это поле необязательное. Если вам оно не нужно, то установите значение этой настройки в null.
- delete: булево значение. Установите в true если хотите чтобы осуществлялось «мягкое удаление», в false – для полного, безвозвратного удаления. По-умолчанию — true.
- find: тоже булево значение. True – для автоматического добавления условий поиска для выборки только не-удаленных записей. False – для поиска по всем записям. По-умолчанию – true.
Любые другие атрибуты в массиве настроек в формате имя => значение будут рассматриваться компонентом как значения для полей с указанным именем для установки в момент удаления.
Например, вы хотите чтобы при удалении записи из модели Article поле published устанавливалось в 0, а также не хотите чтобы компонент автоматически фильтровал при поиске «удаленные» записи:
<?php class Article extends AppModel { var $name = 'Article'; var $actsAs = array('SoftDelete' => array('find' => false, 'published' => '0')); } ?>
3. Изменение стандартных условий поиска
Если не установить параметр find в false, то компонент Soft Delete будет автоматически добавлять специальные условия поиска ко всем вызовам find(), так что модель будет возвращать только не помеченные как удаленные записи.
Таким образом, с помощью этого параметра вы можете полностью выключить спец-условия поиска. Если же в каких-то случаях вам они нужны, а в каких-то нет, то можно управлять условиями прямо из вызовов.
<?php class ArticlesController extends AppController { var $name = 'Articles'; function index() { $articles = $this->Article->findAll(array('Article.deleted' => array(0, 1))); $this->set('articles', $articles); } } ?>
В этом примере, вы получите и «удаленные» и не-«удаленные» записи, благодаря установке условия отбора по полю deleted. Такой вызов не зависит от параметра find компонента.
4. Дополнительные функции компонента
Также можно временно отключить автоматическое добавление спец-условий, а затем включить обратно с помощью функции компонента enableSoftDeletable(). Она принимает булеву переменную: true для включения условий, false – для выключения.
<?php class ArticlesController extends AppController { var $name = 'Articles'; function index() { $this->Article->enableSoftDeletable(false); $articles = $this->Article->findAll(); $this->Article->enableSoftDeletable(true); $this->set('articles', $articles); } } ?>
Обратите внимание, что при вызове функции enableSoftDeletable() только с одним параметром, вы выключаете не только условия поиска, а полностью всю работу компонента, т.е. записи будут удаляться насовсем. Если вы хотите выключить только условия поиска, то безопаснее указать это:
<?php class ArticlesController extends AppController { var $name = 'Articles'; function index() { $this->Article->enableSoftDeletable('find', false); $articles = $this->Article->findAll(); $this->Article->enableSoftDeletable('find', true); $this->set('articles', $articles); } } ?>
Если вам нужно удалить какую-то запись насовсем, то можно временно выключить функции «мягкого удаления»:
<?php class ArticlesController extends AppController { var $name = 'Articles'; function index() { $this->Article->enableSoftDeletable('delete', false); $this->Article->del(1); } } ?>
Или можно для этого же использовать специальную функцию hardDelete():
<?php class ArticlesController extends AppController { var $name = 'Articles'; function index() { $this->Article->hardDelete(1); } } ?>
Если вы хотите очистить таблицу от всех «мягко удаленных» записей и полностью уничтожить их, используйте метод purge():
<?php class ArticlesController extends AppController { var $name = 'Articles'; function index() { $this->Article->purge(); } } ?>
5. Восстановление записей
Каждую «мягко удаленную» запись можно легко восстановить с помощью метода undelete().
В следующем примере запись сначала удаляется, выводится список всех записей чтобы удостовериться что она удалена, а затем запись восстанавливается и это опять проверяется списком:
<?php // Удаляем запись с ID 1 $this->Article->del(1); // Отображаем все записи (автоматические условия включены, // поэтому будут показаны только не-удаленные записи) debug($this->Article->findAll()); // Восстанавливаем удаленную запись $this->Article->undelete(1); // Отображаем все записи debug($this->Article->findAll()); ?>
Январь 8th, 2009 at 13:29
[...] его проекта Cake Syrup. О другой интересной составляющей, SoftDeletableBehavior, недавно, кстати, можно прочесть здесь.Это расширение не использует Inflector::slug() — когда оно [...]
Февраль 2nd, 2009 at 13:36
Очень интересный блог, и очень хотелось бы узнать, продолжение материала будет. А то у же целый месяц прошёл, а не одной новой статьи так и не появилось
Февраль 9th, 2009 at 10:21
Продолжение обязательно будет. Сейчас работаю над большим проектом, поэтому совершенно нет времени. Как только сдадим (думаю, уже на днях) - продолжу наполнение блога.