Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Filtrando precios con operadores

24/27
Recursos

Aportes 9

Preguntas 0

Ordenar por:

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

Si intentas realizar un query con limit y offset, o solo con price, veras que tendras el error de price_max is required, para poder utilizar las demas queries solo tienes que agregar required() en la opción is de price_max

price_max: price_max.when('price_min', {
    is: Joi.number().integer().required(),
    then: Joi.required(),
  }),

También puedes simplificar un poco la opción is

const price_min = Joi.number().integer();

price_max: price_max.when('price_min', {
    is: price_min.required(),
    then: Joi.required(),
  }),

Leyendo un poco la documentación, encontré otro operador que puede funcionar para este momento y es el operador Op.between:
.

options.where.price = {
  [Op.between]: [price_min, price_max],
};

Fuente: Variable | Sequelize


.
Además, en la documentación de Joi encontré una manera de validar que el valor que se envíe en price_max sea mayor a price_min ya que por defecto si se envía estos datos, se retornara un array vacío y probablemente sea mejor manera el error:

const queryProductSchema = Joi.object({
  limit,
  offset,
  price,
  price_min,
  price_max: price_max.greater(Joi.ref('price_min')),
})
  .with('price_min', 'price_max')
  .with('price_max', 'price_min');


,


Y por último, with() es una condicional donde el primer parámetro demanda la presencia de los parámetros siguientes para ser válida. Este segundo parámetro puede ser un string o un array.
Fuente: API Reference | joi.dev

Aún con la validación de price_max cuando se envía el parámetro price_min, se requiere otra validación para solicitar el parámetro price_min cuando se envía price_max, la opción que viene en la misma documentación es la siguiente:

Recuerden guardar la data si hacen cambios directamente en pgAdmin:

En product.schema reemplace:

is: Joi.number().integer(),

Por:

is: Joi.exist()

Esto debido a que al hacer un GET sin querys, me daba el error de que price_max era obligatorio.

está chévere la implementación del filtrado, pero creo que se le está agregando mucha responsabilidad y complejidad al método find, tal vez si de pronto se aísla la lógica del where en otro lugar podríamos bajar tanto la responsabilidad y complejidad.
Para finalizar el método find si le siguiéramos agregando más lógica se nos podría volver un todo poderoso(anti patrón) 😅

Esto del filtro estuvo super!!!

Hermosa documentación la de sequelize

https://sequelize.org/docs/v6/getting-started/

Se hace el uso de operadores para hacer un filtrado de precios. Los operadores sirven para hacer >, <, =, ≥, etc. Los operadores se requieren de la siguiente manera: const { Op } = require('sequelize');.

También se puede hacer uso de WHERE utilizando la instrucción where con los atributos deseados.

El filtrado de precios también se hace con query params. Para recibir el precio se hace un ajuste en el schema.

product.schema.js Se hace la validación para que si se envía un precio mínimo, también se envíe un precio máximo.:

const price = Joi.number().integer().min(10);
const price_min = Joi.number().integer();
const price_max = Joi.number().integer();

const limit = Joi.number().integer();
const offset = Joi.number().integer();

const queryProductSchema = Joi.object({
  limit,
  offset,
  price,
  price_min,
  price_max: price_max.when('price_min', {
    is: Joi.number().integer().required(),
    then: Joi.required(),
  }),
});

También se hace la modificación correspondiente en el servicio, en las options se agrega where con un objeto vacío. Si viene un price en la query params, entonces se agrega a las options. De esta manera se hará un filtrado de productos con el precio exacto que venga en los parámetros query.

En el caso de precio mínimo y máximo, se hace una validación por si vienen en los query params. Se hace el uso de los operadores de sequelize usando Op.gte para ≥ al precio mínimo y Op.lte para ≤ al precio máximo.

product.service.js:

async find(query) {
    const options = {
      include: ['category'],
      where: {},
    };
    const { limit, offset } = query;
    if (limit && offset) {
      options.limit = limit;
      options.offset = offset;
    }

    const { price } = query;
    if (price) {
      options.where.price = price;
    }

    const { price_min, price_max } = query;
    if (price_min && price_max) {
      options.where.price = {
        [Op.gte]: price_min,
        [Op.lte]: price_max,
      };
    }

    const products = await models.Product.findAll(options);
    return products;
  }