public function save($validate = true)
    {
        if ($validate) {
            if (!$this->validate()) {
                return false;
            }
        }
        if (!$this->beforeSave()) {
            return false;
        }
        if ($this->_isNewRecord) {
            $r = $this->_db->table($this->_tableName)->insert($this->_updatedAttributes);
            if (is_string($this->_pk)) {
                $this->{$this->_pk} = $r;
                $this->_originalPk = $this->{$this->_pk};
            } else {
                foreach ($this->_pk as $k) {
                    $this->_originalPk[$k] = $this->$k;
                }
            }

            $this->_isNewRecord = false; // so that the next save won't do another insert
            $this->reload();  // to get extra default values.
            $this->afterSave();
            if (is_string($this->_pk) && !$this->{$this->_pk}) {
                return false; // there was an error when saving
            } elseif (!is_string($this->_pk) && !$r) {
                return false;
            }
        }

        if (!$this->_updatedAttributes) {
            $this->afterSave();
            return true; // nothing to save.
        }

        if (is_array($this->_pk)) {
            $c = $p = [];
            foreach ($this->_originalPk as $k => $v) {
                $c[] = "`$k` = :pk_$k";
                $p[":pk_$k"] = $v;
            }
            $r = (bool)$this->_db->table($this->_tableName)
                ->where(implode(" AND ", $c), $p)
                ->update($this->_updatedAttributes);
        } else {
            $r = (bool)$this->_db->table($this->_tableName)
                ->where("`{$this->_pk}` = :__pk")->setParam(':__pk', $this->_originalPk)
                ->update($this->_updatedAttributes);
        }
        if ($r) { // in case it saved the data then make it look like new.
            $this->_updatedAttributes = [];
            if (is_array($this->_pk)) {
                foreach ($this->_pk as $k) {
                    $this->_originalPk[$k] = $this->$k;
                }
            } else {
                $this->_originalPk = $this->{$this->_pk};
            }
        }

        $this->afterSave();

        return $r ?: true;
    }