Vincit / objection.js

An SQL-friendly ORM for Node.js
https://vincit.github.io/objection.js
MIT License
7.26k stars 636 forks source link

Adding dynamic hooks #1358

Closed jeroni closed 5 years ago

jeroni commented 5 years ago

I am trying to dynamically add hooks to Objection. The problem I had is that in Objection hooks must be statically set on classes. I have implemented a custom class to handle this, here you have an example:

// CustomHooks allows to register listeners at runtime
const updatedModel = await transaction(knexInstance, async (trx) => {
    const builder = modelClass.query(trx);
    await CustomHooks.emit('before_insert', {
        modelClass,
        model: req.body,
        builder,
        trx
    });
    ...

The limitation of this CustomHooks class comes when I use UpsertGraph or InsertGraph and other objects are updated on eager operations. If I could have this information on transaction level to emit an event for every object implied on the graph would be perfect.

Is there any way to access this information?. Are there any global hooks to avoid using event methods ($afterInsert...) in classes?

Will this, or something similar, be possible in the hooks 2.0 API?

koskimas commented 5 years ago

I'm not sure I fully understand what you are trying to do, but have you seen the runBefore query builder method? Maybe you could use and isInsert() method to achieve what you want. No changes to the hooks will be added before 2.0. 2.0 will have a new static hook system.

jeroni commented 5 years ago

I just wanted to add hooks at runtime, similar to this:

http://docs.sequelizejs.com/manual/hooks.html

I understand this won't be possible

class Book extends Model {}
Book.init({
  title: DataTypes.STRING
}, { sequelize });

Book.addHook('afterCreate', 'notifyUsers', (book, options) => {
  // ...
});

Book.removeHook('afterCreate', 'notifyUsers');
koskimas commented 5 years ago

You can easily build that yourself. Adding support to that in your own project would be less tha 10 lines of code.

koskimas commented 5 years ago

Simply collect the hooks in an array and call them from the objection hook. Add an addHook method that pushes to that array.

calebeaires commented 3 years ago

Hey @koskimas, good solution. Could you give us a clue what is on your mind. Help us archive this sequelize thing!