вторник, 20 апреля 2010 г.

Грабля: ругается, что такая запись уже есть в БД

Проблема: при редактировании объекта и отправке формы Доктрина ругается, что
An object with the same "email" already exist
при том, что мы совешенно уверены, что такой email в базе ровно один - у редактируемого объекта. В чем дело? Если случилось так, что форма редактирования объекта содержит embedded-форму, то скорее всего проблема в следующем.

Грабли: символ "-" в названии БД mysql

Не нужно использовать этот символ. Неожиданности гарантированы. Заменяйте на подчеркивание

Грабли: SQLSTATE[HY000]: General error: 1005 Can't create table

Mysql server version: 5.1.40-community
если при составлении схемы была допущена ошибка, которая привела к General error: 1005 при установке CONSTRAINTS (например примари ключ и внешний ключ имеют разные типы), то есть вероятность, что даже после исправления схемы она не сможет создаться: та же ошибка. Это связано с тем, что предыдущие, неправильно связанные таблицы, не могут удалиться: мешает кривой CONSTRAINTS. Решение одно: дропнуть БД (ну или бинарные файлы таблиц).

Лично я столкнулся с этой проблемой, когда в симфонии 1.4 случайно использовал sfDoctrineGuardPlugin из ветки 1.2. Выдалась ошибка. Заменил плагин, ошибка осталась. Удалил руками бинарники, пересобрал таблицы - все ок.

вторник, 6 апреля 2010 г.

Грабли: почему теряются пермиссии?

Почему при добавлении новой пермиссии текущему пользователю (через админку, например), в списке $this->getUser()->getCredentials() она не появляется? Дело в том, что набор пермиссий сохраняется в сессии, если включен фильтр sfGuardRememberMeFilter (галочка "Запомнить меня"). Обращения к базе данных в этом случае вообще не происходит. Чтобы новая пермиссия стала доступна текущему пользователю, надо разлогиниться и снова залогиниться.

General error: 1451 Cannot delete or update a parent row: a foreign key constraint fails

Почему при удалении записи возникает SQL-ошибка?
General error: 1451 Cannot delete or update a parent row: a foreign key constraint fails ... 

Потому что при удалении в БД объекты все еще связаны. И поэтому их надо развязать на уровне приложения перед удалением. В методе delete модели нужно добавить отвязку:
  $this->unlink('Tickets',$this->Tickets->getPrimaryKeys(),true);

Это требуется только при наличии связи many-to-many. При других типах связей вполне справляется onDelete: CASCADE. Обратите внимание на третий аргумент (true). Он указывает на то, что unlink надо сделать немедленно, а не помечать связи как "подлежащие удалению".