lox / pheasant

A lightweight data mapper designed to take advantage of PHP 5.3+
http://getpheasant.com
MIT License
101 stars 21 forks source link

Primary key is 0 after updating an object #57

Closed bjornpost closed 11 years ago

bjornpost commented 11 years ago

Hi,

Just found quite a serious bug I think. Here's a simple script to reproduce the problem I'm experiencing:

    $konijn = \Model\Konijn::oneById(7110);
    var_dump($konijn->id); // -> 7110
    $konijn->email = 'foobar@example.com';
    var_dump($konijn->id); // -> 7110
    $konijn->save();
    var_dump($konijn->id); // -> 0

Since we're updating an existing object, I expected $konijn->id to stay 7110. Anyone else that can confirm this behavior?

lox commented 11 years ago

I'm struggling to reproduce this one, could you post your model code?

jorisleker commented 11 years ago

Hi @Lox,

I was able to reproduce it: the bug only manifests itself on models which have primary keys with the auto_increment option set, like so:

    public function properties() {
        return array(
            'id' => new \Pheasant\Types\Integer(5, 'primary auto_increment'),

The error is in the update() method of the RowMapper class:

    /**
     * @see AbstractMapper::update()
     */
    protected function update($object, $changes)
    {
       ...
        // check for auto-increment
        foreach ($object->identity() as $key=>$property) {
            if($property->type->options()->auto_increment)
                $object->{$key} = $result->lastInsertId();
        }
    }

UPDATE statements don't return a lastInsertId, and as a result the primary key on the object is reset to 0 (the entire foreach loop can be removed here, is only needed on INSERT queries)

lox commented 11 years ago

Fixed, good find guys!