bshaffer/csDoctrineActAsSortablePlugin — pull request #13 by robo47 (2012-01-09 18:10:47+00:00)
Title: Fix problem with batchdelete and not-up2date records

I experienced this bug with the symfony-admingenerator with a "batchdelete" with mysql (a database which supports the update with orderby).

The problem is the following, given I delete multiple records, the "loop" for deleting the records looks like this in symfonys templates:

```php

protected function executeBatchDelete(sfWebRequest $request)
{
$ids = $request->getParameter('ids');

$records = Doctrine_Query::create()
->from('getModelClass() ?>')
->whereIn('getPrimaryKeys(true) ?>', $ids)
->execute();

foreach ($records as $record)
{
$this->dispatcher->notify(new sfEvent($this, 'admin.delete_object', array('object' => $record)));

$record->delete();
}

$this->getUser()->setFlash('notice', 'The selected items have been deleted successfully.');
$this->redirect('@getUrlForAction('list') ?>');
}

```

Given the following data:

```
categories
| id | name |
| 1 | foo |

images
| id | category_id | filename | position |
| 1 | 1 | 1.jpg | 1 |
| 2 | 1 | 2.jpg | 2 |
| 3 | 1 | 3.jpg | 3 |
| 4 | 1 | 4.jpg | 4 |
| 5 | 1 | 5.jpg | 5 |
| 6 | 1 | 6.jpg | 6 |

```

In the loop the postDelete-Hook is triggered, which works perfectly for the first entry:

Deletequery:

```sql
DELETE FROM aw_gallery_image WHERE image_id = 1
```

postDeleteHook-Query:

```sql
UPDATE aw_gallery_image SET position = position - 1 WHERE (position > 1 AND category_id = 1) ORDER BY position
```

Now images looks like this:

```
| id | category_id | filename | position |
| 2 | 1 | 2.jpg | 1 |
| 3 | 1 | 3.jpg | 2 |
| 4 | 1 | 4.jpg | 3 |
| 5 | 1 | 5.jpg | 4 |
| 6 | 1 | 6.jpg | 5 |
```

since we didn't refresh the second entry, in our loop it still is.

id: 2
position: 2

which when deleted results in

```sql
DELETE FROM aw_gallery_image WHERE image_id = 2
```
and the triggered postDeleteHook-Query, which fails.

```sql
UPDATE aw_gallery_image SET position = position - 1 WHERE (position > 2 AND category_id = 1) ORDER BY position
```

Before the update fails (and after), the database looks like

```
| id | category_id | filename | position |
| 3 | 1 | 3.jpg | 2 |
| 4 | 1 | 4.jpg | 3 |
| 5 | 1 | 5.jpg | 4 |
| 6 | 1 | 6.jpg | 5 |
```

The update-query would try to make position 3 a 2 which will result in

```
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '2-1' for key 'images_position_sortable_idx'
```

My proposed solution would be to refresh the record in the preDelete-hook, so it is up2date in the postDelete-hook, since there, the record is already deleted and we can't refresh it anymore.