Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Crear, actualizar y eliminar

11/27
Recursos

Aportes 11

Preguntas 12

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

para el reto hice un middleware como menciono el profe el código quedo así

function queryErrorHandler(err, req, res, next) {
  if (err.parent) {
    const { fields, parent } = err;
    res.status(500).json({
      field: fields,
      message: parent.detail,
    });
  }
  next(err);
}

la propiedad fields y parent vienen dentro del error que se genera cuando se hace la consulta a la base de datos

la respuesta se ve así

{
  "field": {
    "email": "[email protected]"
  },
  "message": "Key (email)=([email protected]) already exists."
}

CRUD Operations

En mi caso, sigo ocupando node-postgres para el desarrollo del CRUD.
ℹ️ Repositorio: Link
.
✨Adicionamos un formato para dar estructura a nuestro request. Con ello, podremos acomodar la instancia para su uso.

    /**
     * @private
     * @description format data structure
     * @param {object} body - body request
     * @returns {object} - { fields, values, tuples }
     */
    #formatStructure(body) {
        return {
            fields: Object.keys(body).join(),
            values: Object.values(body),
            tuples: Object.entries(body).map(([key, value]) =>
                format(`${key} = %L`, value)
            ),
        };
    }

.
♻️ Modificamos nuestras funcionalidades para dar servicio a las demás operaciones de CRUD

    /**
     * @description find all registers in table
     * @returns {array} - response query postgresDB as array
     */
    async findAll() {
        return await this.client.query(`SELECT * FROM ${this.table}`);
    }
    /**
     * @description create a register in table
     * @param {object} body - body request
     * @returns {array} - response query postgresDB as array
     */
    async create(body) {
        const { fields, values } = this.#formatStructure(body);
        const request = format(
            `INSERT INTO ${this.table}(${fields}) VALUES(%L) RETURNING *`,
            values
        );
        return await this.client.query(request);
    }
    /**
     * @description updates parcials of a register in table
     * @param {object} param - param request
     * @param {object} body - body request
     * @returns {array} - response query postgresDB as array
     */
    async update({ id }, body) {
        const { tuples } = this.#formatStructure(body);
        const request = format(
            `UPDATE ${this.table} SET ${tuples} WHERE id = ${id} RETURNING *`
        );
        return await this.client.query(request);
    }
    /**
     * @description delete a register in table
     * @param {object} param - param request
     * @returns {array} - response query postgresDB as array
     */
    async delete({ id }) {
        const request = format(
            `DELETE FROM ${this.table} WHERE id = ${id} RETURNING *`
        );
        return await this.client.query(request);
    }

Resolví el middleware de esta manera:

const { ValidationError } = require('sequelize')
function handleSQLError (err, req, res, next) {
  if (err instanceof ValidationError) {
    throw boom.conflict(err.errors[0].message)
  }
  next(err)
}

Y lo añadí en mi index.js

app.use(logErrors)
app.use(handleSQLError)
app.use(boomErrorHandler)
app.use(errorHandler)

Para el reto este es el middleware que hice:

export function sequelizeErrorHandler (error: ValidationError, req: Request, res: Response, next: NextFunction) {
  if (error instanceof ValidationError) {
    res.status(409).json({
      'statusCode': 409,
      'error': error.errors[0].type,
      'message': error.errors[0].message
    });
  }
}

El tipado es que estoy haciendo el proyecto en TypeScript, el formato que mando es exactamente igual que el que manda Boom

users.service.js:

const boom = require('@hapi/boom');
const { models } = require('../libs/sequelize');

class UserService {
  constructor() {}
  async create(data) {
    const newUser = await models.User.create(data);
    return newUser;
  }

  async find() {
    const rta = await models.User.findAll();
    return rta;
  }

  async findOne(id) {
    const user = await models.User.findByPk(id);
    if (!user) {
      throw boom.notFound('User not found');
    }
    return user;
  }

  async update(id, changes) {
    const user = await this.findOne(id);
    const rta = await user.update(changes);
    return rta;
  }

  async delete(id) {
    const user = await this.findOne(id);
    await user.destroy();
    return { id };
  }
}

module.exports = UserService;

Me parece excelente la explicación de la validación que hace el profe al inicio de la clase.
Son muchas cosas y conceptos que se van acumulando.

No olviden levantar la base de datos y el administrador gráfico cada vez que vayan a lanzar el proyecto.

- docker-compose up -d pgadmin
- docker-compose up -d postgres

Por convencion estaba yo llamando a la funcion de findOne cuando el profe comienza a hacerlo :3 Muy bien por el profe

SOLUCION AL PROBLEMA:
ID NOT NULL
CREATE_AT NOT NULL
.
He visto en muchos comentarios (sin respuesta) que tenían inconvenientes con el id y create_at de su DB. Y es en que en la configuración de user.model.js esta diseñada de manera que asigne valores por default al id y create_at pues el cliente no debe ser capaz de añadir esos datos en el método POST.
.
El detalle es que al crear la tabla no se asigna ningún defaultValue. Esto pasa porque las propiedades de Sequelize no están funcionando correctamente, por lo que recomiendo:
.
1 - Actualizar todas las dependencias
2 - Borrar la tabla Users desde pgadmin
3 - Correr nuestra aplicación.
4 - Verificar desde Pgadmin que id y create_at tienen sus respectivos defaultValues asignados.
(P.D: Así solucione el problema con el id).
.
En caso de que create_at siga arrojando problemas, recomiendo utilizar la configuracion para createdAt en user.model.js:

createdAt: {
    allowNull: false,
    type: DataTypes.DATE,
    field: 'create_at',
    defaultValue: Sequelize.fn("NOW")
  }

Sequelize.fn(“NOW”) es una poor solution para el problema de Sequelize.NOW del que podras encontrar mas información aquí.
.
Luego de aplicar estos cambios, repetir los pasos 2, 3 y 4.
.
Espero les sirva

Si alguien tiene problemas con el Update y el destroy en la documentación de Sequelize se utilizan estos 2 metodos

  const rta = models.User.update(changes,{
      where:{id}
    })
    const rta = await models.User.destroy({where: {id}})
    return rta

Ya puedo modificar datos de mi tabla con el crud!! genial