views:

679

answers:

3

I want to work with versioned ActiveRecord associations. E.g., I want to find the object that another object belongs_to as of a certain past date, or the one that it belonged to before that. Does there already exist a library subclassing Rails' ActiveRecord to provide versioned relations? Or some other Ruby library which provides persistable versioned relations?

+1  A: 

Supporting historical state in a transactional application is a good way to massively expand complexity, slow DB performance and make life difficult for yourself. If you only need to display or report on historical state and do not need it up to the minute consider building a star schema with Type-II slowly changing dimensions and a periodic process that updates it.

This will be substantially less complex than building an application with systemic ad-hoc history tracking running through the code base. If this approach will do what you require of the application you will probably be better off doing it. It also means that the application database will play nicely with the vanilla database access mechanisms that come with the system.

If you need reasonably frequent refresh you can implement a changed-data capture system on the database, which is relatively simple if the application only has to be concerned with current state. With a CDC mechanism the load process only has to update based on changes and will run relatively quickly.

ConcernedOfTunbridgeWells
+6  A: 

Try the ActsAsVersioned plugin

Ken Mayer
+2  A: 

Provided you're not dealing with huge amounts of data, and the extra temporal dimension won't push your db over the edge, there are no major downsides to historically versioned data. Extra query complexity can be a slight pain, but it's nothing major.

In my case I wrote a rails plugin that handles versioning, it adds 5 columns to each versioned table (and helps handle querying/manipulation etc):

valid_from - datetime - the datetime that this version was created at

valid_to - datetime - the datetime that this version stopped being valid

root_id - integer - the id of the original row (that this is a subsequent version of)

created_by - integer - The user id of the user that performed the creation of this version

retired_by - integer - The user id of the user that retired this version

For currently active rows, valid_to is null. Adding an index on valid_to aids in keeping performance snappy.

Michael
Disagree with 'slight'. On an insurance underwriting system I am somewhat familiar with the estimates are that the history tracking added in a particular version accounts for about 70% of the development effort.
ConcernedOfTunbridgeWells
Interesting, my personal experience sways the other way somewhat, but I designed the system to be versioned from the ground up. I'd rather not imagine the pain it would take to add it in a later version. The system had approx 20 versioned tables, 10 unversioned.
Michael
Hm, this sounds very interesting! Did you release your plugin somewhere? Could you upload it to github? I'd love to look at it to get some ideas etc.
reto