Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object versioning in Rails, like Papertrail but individual tables

For a project I'm currently working on I need to implement object versioning. Unfortunately I need to keep a full history of each object, so a single table solution like Papertrail would quickly become un-manageable. There are features of Papertrail which I like, however, which I haven't been able to find in a solution with individual tables for each model (such as acts_as_versioned).

  • Ability to store meta-information from both controller and model
  • Data is serialized so schema changes don't modify the version table
  • Powerful methods for traversing versions
  • Automatic tracking of change responsibility

There are also some features which Papertrail does not have which would be bonuses:

  • Built-in version diff support
  • Differential instead of full versions

I am currently considering forking Papertrail to use individual tables for each model, but would like to save that effort if there's an existing solution.

Update: Vestal Versions by default uses a single table, but by providing a custom version class for each model and using the "set_table_name" method of ActiveRecord, I was able to create separate tables for each model. Vestal Versions also has built in diff support, though its interface isn't as powerful as Papertrails. It also lacks association support.

Update 2: As papertrail seems to be a more active project I've forked the gem and added in custom class support similar to vestal versions which now allows for the ability to define separate tables per model. My fork is here, but I hope it will be pulled into the main project repository shortly. https://github.com/benzittlau/paper_trail

like image 990
Ben Zittlau Avatar asked Mar 17 '11 23:03

Ben Zittlau


1 Answers

You can specify custom version subclasses with the :class_name option:

class Post < ActiveRecord::Base
  has_paper_trail :class_name => 'PostVersion'
end

class PostVersion < Version
  # custom behaviour, e.g:
  self.table_name = :post_versions # in rails 2, use set_table_name
end

This allows you to store each model's versions in a separate table, which is useful if you have a lot of versions being created.

like image 104
Dennis Krupenik Avatar answered Sep 18 '22 16:09

Dennis Krupenik