codeigniter-base-model icon indicating copy to clipboard operation
codeigniter-base-model copied to clipboard

delete_by() function doesn't have correct return, possibly others

Open facultymatt opened this issue 13 years ago • 4 comments
trafficstars

The function delete_by() will always return 1, even if nothing was deleted. To fix this the function should return $this->db->affected_rows(); instead of $result

Detailed example below with added code for debugging:

  /**
     * Delete a row from the database table by an arbitrary WHERE clause
     */
    public function delete_by()
    {
        $where = func_get_args();
        $this->_set_where($where);

        // added comment
        log_message('error', '$where params are:' . print_r($where, true));

        $where = $this->trigger('before_delete', $where);

        if ($this->soft_delete)
        {
            $result = $this->db->update($this->_table, array( $this->soft_delete_key => TRUE ));
        }
        else
        {
            $result = $this->db->delete($this->_table);
        }

        $this->trigger('after_delete', $result);

        // added comment
        log_message('error', '$result is:' . print_r($result, true));
        log_message('error', 'affected->rows is:' . print_r($this->db->affected_rows(), true));

        return $result;

    }

When you run the above code you'll notice that $result is always 1, even when nothing was deleted or updated. In comparison $this->db->affected_rows is accurate, showing 0 if nothing was updated and the number of affected rows if something was updated or deleted.

This same return happens in a few other spots, namely the update and delete functions.

The only logic I see for possibly returning $return is if we wanted to return the ACTUAL affected rows in cases of update, sending them back to the function as an object or array. However in this case I think you need to do another get using the updated ids, not 100% sure though.

facultymatt avatar Sep 08 '12 17:09 facultymatt

From my understanding, $result is returning TRUE because the DB ran the query successfully. Generally, you would know if the records exist before you delete them anyway. Then use $this->db->affected_rows() to compare the number of rows that you expected to be affected, to the number of rows that were actually affected.

But, perhaps a MY_Model::affected_rows() method should be added for consistency?

inda5th avatar Sep 13 '12 21:09 inda5th

@inda5th your statement "$result is returning TRUE because the DB ran the query successfully" is correct, however just because the query was successfully ran doesn't mean anything was changed, it just means the query didn't break or fail.

For example, if you pass an incorrect ID (that doesn't exisit) to delete_by() nothing will be deleted but $result would still be true. This is where affected_rows() comes in handy, because you can check against it to make sure thing worked as expected.

I like your idea of adding MY_Model::affected_rows() but it seems more straightforward just return affected_rows() from each function, because I really don't see the need to $result as it stands now.

facultymatt avatar Sep 16 '12 19:09 facultymatt

Okay, if someone wants to write a test and change the value of $result to be affected_rows(), that'd be awesome. It's going to be a while before I get the chance!

jamierumbelow avatar Sep 30 '12 10:09 jamierumbelow

Thanks for the fix !

dawondyifraw avatar Jul 30 '15 12:07 dawondyifraw