public function update(Model $m, $id, $data)
    {
        if (!$m->id_field) {
            throw new Exception(['id_field of a model is not set. Unable to update record.']);
        }

        $update = $this->initQuery($m);
        $update->mode('update');

        $data = $this->typecastSaveRow($m, $data);

        // only apply fields that has been modified
        $update->set($data);
        $update->where($m->getField($m->id_field), $id);

        $st = null;

        try {
            $m->hook('beforeUpdateQuery', [$update]);
            if ($data) {
                $st = $update->execute();
            }
        } catch (\PDOException $e) {
            throw new Exception([
                'Unable to update due to query error',
                'query'      => $update->getDebugQuery(false),
                'model'      => $m,
                'conditions' => $m->conditions,
            ], null, $e);
        }

        if ($m->id_field && isset($data[$m->id_field]) && $m->dirty[$m->id_field]) {
            // ID was changed
            $m->id = $data[$m->id_field];
        }

        $m->hook('afterUpdateQuery', [$update, $st]);

        // if any rows were updated in database, and we had expressions, reload
        if ($m->reload_after_save === true && (!$st || $st->rowCount())) {
            $d = $m->dirty;
            $m->reload();
            $m->_dirty_after_reload = $m->dirty;
            $m->dirty = $d;
        }
    }