Lucid: Model .delete() should support transactions

Created on 14 Jun 2019  路  7Comments  路  Source: adonisjs/lucid

Why this feature is required (specific use-cases will be appreciated)?

We are developing a REST API with the goal of full CRUD. Transaction support is great for create() and update(), but we'll need it as well for .delete().

I was able to clone and make the change myself, which appears to work for our simple implementation, but I'm not sure if submitting a PR is appropriate. I don't fully understand the object life cycle, and I suspect there would be problems in the event of a rollback after delete. I don't know the "correct" way to handle that.

Have you tried any other work arounds?

Directly calling the knex methods would work, but that is obviously not part of the lucid pattern.

Are you willing to work on it with little guidance?

Sure, but as I said I don't have a deep understanding of what the impact of rollback would be on the object.

High Major Bug

Most helpful comment

I spent two days struggling to make this work on Adonis 4.1 / Lucid 6.1.3. I hope this helps someone.

async destroy({ response, params }) {
    const { id } = params;

    try {
      const moeda = await Moeda.findOrFail(id);

      await Database.transaction(async trx => {
        await trx('moedacotacao').where('moeda_id', id).del();
        // I tested manually throwing an exception here and it's being caught and rolled back properly.
        await trx('moeda').where('id', id).del();
      });

      return moeda;
    } catch (err) {
      return response
        .status(400)
        .send([{ message: 'N茫o foi poss铆vel deletar'}]);
    }
}

All 7 comments

Should be good with @adonisjs/[email protected]

Do you have any ETA for @adonisjs/[email protected]?

The ETA is Adonis 5, which has no ETA at the moment. 馃槤

I spent two days struggling to make this work on Adonis 4.1 / Lucid 6.1.3. I hope this helps someone.

async destroy({ response, params }) {
    const { id } = params;

    try {
      const moeda = await Moeda.findOrFail(id);

      await Database.transaction(async trx => {
        await trx('moedacotacao').where('moeda_id', id).del();
        // I tested manually throwing an exception here and it's being caught and rolled back properly.
        await trx('moeda').where('id', id).del();
      });

      return moeda;
    } catch (err) {
      return response
        .status(400)
        .send([{ message: 'N茫o foi poss铆vel deletar'}]);
    }
}

Worked perfectly

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

UPDATE: I have been using this trait and it's working well so far

'use strict';

class SafeDelete {
  register(Model, customOptions = {}) {
    const defaultOptions = {};
    const options = Object.assign(defaultOptions, customOptions);
    const safeDelete = async function(trx) {
      return trx
        .from(Model.table)
        .where(Model.primaryKey, this[Model.primaryKey])
        .del();
    };

    Model.prototype.safeDelete = safeDelete;
  }
}

module.exports = SafeDelete;
Was this page helpful?
0 / 5 - 0 ratings

Related issues

hectorgrecco picture hectorgrecco  路  3Comments

enniel picture enniel  路  7Comments

Karnith picture Karnith  路  5Comments

HigoRibeiro picture HigoRibeiro  路  3Comments

moar55 picture moar55  路  4Comments