Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Versioning domain instances for approval in Grails

I’m looking for the best approach to extend the Grails CRUD generation functionality. It should be a Grails plugin which provides additional generators for following functionality:

  • Any changes on extended domain instance should be saved (as a version of it) for history
  • Only one version of an instance can be active
  • User should be able to activate a version of the instance (the currently active instance should be deactivated) which is not created by him (4 eyes principle)
  • A diff view is nice to have

The intervention into Grails out of the box scripts should be as small as possible. I identified so far 3 design strategies for implementation:

  1. Mirror table with the same schema, which contains versions (doubles the count of domains/tables). The activated version will be copied to the native domain and vice versa.
  2. Using discriminator in the domain class. Some new columns will be added to the domain (like state [active,notActive], lastUpdatedBy, lastUpdatedDate…)
  3. (De-)Serializing instances to a special domain with BLOB (e.g domain.properties as JSON)

Any of the solutions has pros and cons. What is the best approach to implement it? Perhaps there is a more simple way.

like image 797
Waldemar Avatar asked Jan 13 '14 13:01

Waldemar


1 Answers

I've been developing a system in Grails that makes intense use of the version concept (as you related above). My approach was the 2nd one listed in your question.

I've created two fields: internalVersion e disabled. Every class that needs to be Versionable, must implement an interface called Versionable.

I'll try explain here one of the scenarios which it's necessary to use the version functionality (forgive my english).

The system that uses this concept is a Commercial System where there is a class called Quote.

Every Quote can has one or more versions where only the last version is valid. Every Quote and its versions are generated based in negotiations with an specific client. This way, a client asks us a Quote and if for some reason he doesn't like the prices (for instance), we can generate a new version with some discount. Every Quote has a unique code following by the current version, example: QT-000022/0 (first version), QT-000022/1 (second version).

To generate a new Version I use a method that clones the current object (using a kind of complete and deep Save As). I copy everything (properties and collections) to a new object.

The clone method identifies that the class implements the Versionable interface and does the following:

oldQuote.disabled = true
newQuote.internalVersion = oldQuote.internalVersion + 1

This way it's possible assure that only one version will be enabled.

I hope you understand my approach.

like image 185
cantoni Avatar answered Sep 21 '22 17:09

cantoni