public function routePutUpdate(Request $request, Response $response, $args)
    {
        if (!$this->authorization->isAuthorized(constant(strtoupper($this->routePrefix)."_UPDATE_RESOURCE"))) {
            throw new \Exception('No permission.');
        }

        $primaryKeyValue = $args[ROUTEARG_PRIMARY_KEY];

        /** note that boolean columns that don't exist in request input are added as false */
        $this->setRequestInput($request, DatabaseTableForm::getFieldNames($this->tableMapper), $this->tableMapper->getBooleanColumnNames());

        $redirectRoute = SlimPostgres::getRouteName(true, $this->routePrefix, 'index');

        // make sure there is a record for the primary key
        if (null === $record = $this->tableMapper->selectForPrimaryKey($primaryKeyValue)) {
            return $this->databaseRecordNotFound($response, $primaryKeyValue, $this->tableMapper, 'update');
        }

        // if no changes made stay on page with error
        $changedColumnsValues = $this->getMapper()->getChangedColumnsValues($this->requestInput, $record);
        if (count($changedColumnsValues) == 0) {
            SlimPostgres::setAdminNotice("No changes made", 'failure');
            return $this->view->updateView($request, $response, $args);
        }

        $validator = new DatabaseTableUpdateFormValidator($this->requestInput, $this->tableMapper, $record);

        if (!$validator->validate()) {
            // redisplay the form with input values and error(s)
            FormHelper::setFieldErrors($validator->getFirstErrors());
            $args[SlimPostgres::USER_INPUT_KEY] = $this->requestInput;
            return $this->view->updateView($request, $response, $args);
        }

        $this->tableMapper->updateByPrimaryKey($changedColumnsValues, $primaryKeyValue);

        $this->enterEventAndNotice('update', $primaryKeyValue);

        return $response->withRedirect($this->router->pathFor($redirectRoute));
    }