sdepold/sequelize — pull request #353 by lemon-tree (2012-12-03 02:00:50+00:00)
Title: Added pre/post events for save, build and destroy

As brought up in https://github.com/sdepold/sequelize/issues/346 I also found the need for listening for events across my application and have put together the following solution for handling events within Sequelize.

Hence, I have implemented six events (and tests) that can be used throughout Sequelize:
- preSave
- postSave
- preBuild
- postBuild
- preDestroy
- postDestroy

These events are built upon Node's default EventEmitter system, so its behavior is familiar. You can listen for the events with a callback on one of three levels using the default Node event pattern:
- Global level : Using Sequelize.on('preSave', func) will result in func being called before a save on any DAO object under the control of the Sequelize ORM.

- Factory level : Using someDAOFactory.on('preSave', func) will result in func being called before any save on all instances created by that specific DAO factory.

- Instance level : Using someInstance.on('preSave', func) will result in func being called only before a save on the specific instance being listened to.

The events originate at the instance level (except for build events) and bubble up (analogous to DOM events bubbling). The pre/post Save and pre/post destroy events are available at all levels, but the pre/post Build events are available everywhere except at instance level as obviously you can't attach listeners to an object that doesn't exist yet. Also, by using this listener pattern, we have allowed for multiple functions to listen for the same events, meaning you can logically separate the event processing.

The form of the arguments passed to the event callbacks are as so:
function (daoInstance, daoDactory)
Where daoInstance is the instance associated with the event and daoFactory is the factory that produced the instance. In preBuild and postDestroy events, the daoInstance passed is null.

This design also leaves scope for adding many other types of events that can bubble up from instance level, although there is currently a filter between each level to prevent unexpected events bubbling up to the top global level.

The tests I have produced for the event system may be overkill but should cover the scope of what these events achieve and all are passing locally.