Collin O'Neill Tue Mar 13 14:38:18 -0400 2012

Subject: RecordNotFound when deleting model. Delete before find? Or find after delete?

Hi everyone, I'm new to ActiveRecord but while refactoring some applications, I'm really enjoying the flexibility of ORM.

I seem to be running into a problem when deleting a record.

$id = $_GET['idcontacts'];
$o = contact::find($id);
$success = $o->delete();

Throws a RecordNotFound:
Fatal error: Uncaught exception 'ActiveRecord\RecordNotFound' with message 'Couldn't find contact with ID=10526' in [...]/php-activerecord/lib/Model.php:1589

class contact extends ActiveRecord\Model {
static $table_name = 'contacts';
static $primary_key = 'idcontacts';
} // END CLASS

The record is deleted correctly, but then contact::find() throws a RecordNotFound error? It appears that find() is still trying to find the record after deletion? I can replicate the problem with stable 1.0 and the latest nightly build.

Does anyone know why this would be?

BTW if I run a test without $_GET variables, it's works fantastically:

$attributes = array('first_name' => 'please','last_name' => 'delete','company' => 'me',);
$o = new contact($attributes);
$o->save();
$id = $o->id;
$o = contact::find($id);
$success = $o->delete($id);

Thanks!


Max Schwanekamp Fri Mar 16 03:00:10 -0400 2012

Collin, just to rule out the obvious, you should test if the record exists first.

That is, you should be doing something like:

$id = $_GET['idcontacts'];
try {
    $o = contact::find($id);
}
catch (ActiveRecord\RecordNotFound $e) {
    //handle the error, or at a minimum:
    echo 'Cannot delete the record, because it could not be found.'
          .$e->getMessage()
          .$e->getTraceAsString();
    exit();
}
$success = $o->delete(); // you can wrap this in a try...catch as well

Or you can use contact::exists($id) instead of the try...catch, but exists() adds another query just to check if the object exists.

Collin O'Neill Fri Mar 16 10:34:15 -0400 2012

Max, thanks very much for the response. I looked at the calling script and discovered it had two references to the action handler, one in the link URL and one through a Javascript confirmation dialog box.

<a 
  href="?a=d&idcontacts=403" 
  onClick=" 
    if (confirm('This will delete the contact! Are you sure?')) { 
      window.location='?a=d&idcontacts=403'; 
    }" 
>
delete user
</a>

So, it was a simple mistake that had nothing to do with ActiveRecord. I fixed it by replacing href="?a=d&idcontacts=403" with href="#" so that only the Javascript function is allowed to call the action handler.

However, you are absolutely right I should catch the RecordNotFound error and handle it along with other errors.

Thanks!

(1-2/2)