es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

ObjeciónJS – Insertar uno a muchos y actualizar el padre.

Hola, soy un principiante en Objection js / Knex. Tengo una entidad Item que se relaciona con otra entidad Bag. Quiero insertar un Item en una Bag y también actualizar el peso de la bolsa según el peso del Item.

Clase Item:

id!: Id;
weight!: number;
bagId?: Id;
bag!: Bag;

static tableName = 'items';

static get relationMappings(): RelationMappings {
    return {
        bag: {
            relation: Base.BelongsToOneRelation,
            modelClass: 'Bag',
            join: {
                from: 'items.bagId',
                to: 'bags.id',
            },
        },
    };
}

Clase Bag:

id!: Id;
totalWight!: number;
items?: Item[] | undefined;

static tableName = 'bags';

static get relationMappings(): RelationMappings {
    return {
        cuboids: {
            relation: Base.HasManyRelation,
            modelClass: 'Item',
            join: {
                from: 'bags.id',
                to: 'items.bagId',
            },
        },
    };
}

Ya he utilizado upsertGraph e intenté usar patchAndFetchById, pero todos parecen quedarse colgados cuando intento actualizar el padre (Bag) e insertar el valor de Item.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para insertar un Item en una Bag y actualizar el peso de la bolsa de acuerdo al peso del Item, puedes utilizar el método transaction proporcionado por Knex. Aquí tienes un ejemplo de código para lograr esto:

    import { Item } from './models/Item';
    import { Bag } from './models/Bag';
    import { transaction } from 'knex';
    
    const datosNuevoItem = {
      weight: 10,
      bagId: bagId // el ID de la bolsa en la que se agregará el ítem
    };
    
    // envuelve el código de transacción en un bloque try-catch para manejar cualquier error
    try {
      await transaction(Item.knex(), async trx => {
        // obtén la instancia del modelo de la bolsa desde la base de datos y bloquea la fila para evitar actualizaciones conflictivas
        const bag = await Bag.query(trx)
          .findById(datosNuevoItem.bagId)
          .forUpdate();
    
        // crea una nueva instancia de Item con los datos proporcionados
        const nuevoItem = await Item.query(trx).insert(datosNuevoItem);
    
        // actualiza el peso de la bolsa y guarda los cambios en la base de datos
        bag.totalWeight += nuevoItem.weight;
        await bag.$query(trx).patch({totalWeight: bag.totalWeight});
      });
    } catch (error) {
      // maneja el error aquí
    }
    

    En este fragmento de código, primero creamos un nuevo objeto Item con los datos proporcionados (datosNuevoItem), que incluye el ID de la Bag a la que queremos agregar el Item. Luego utilizamos el método transaction proporcionado por Knex para ejecutar una transacción que contiene los siguientes pasos:

    1. Obtener la instancia del modelo Bag desde la base de datos utilizando el ID proporcionado en datosNuevoItem. Utilizamos el método forUpdate() para bloquear la fila y evitar actualizaciones conflictivas por parte de otras transacciones.
    2. Utilizar el método insert proporcionado por Objection.js para crear una nueva fila de Item en la base de datos con los datos proporcionados.

    3. Actualizar el peso de la Bag agregando el peso del nuevo Item y actualizar la columna totalWeight de la fila de Bag utilizando el método patch proporcionado por Objection.js.

    Si ocurren errores durante la transacción, el bloque catch los manejará.

    Este fragmento de código asume que ya has inicializado la conexión a tu base de datos y has definido tus modelos de Objection.js (Item y Bag) con los datos de configuración necesarios. Si todavía no lo has hecho, puedes consultar la documentación de Objection.js para obtener más información sobre cómo hacerlo.

Comments are closed.