Versions

A list of libraries to work with ActiveRecord model versioning.

website: zenadmin.org/650

license: MIT

Auto (status: beta)

Duplicate on save if should_clone? returns true.

Multi (status: beta)

Hide many versions behind a single current one. For example if you want to version the content of a Page class, you should add a 'version_id' in the “pages” table to store the current version and you will need a Version model with a “page_id” to link back:

class Version < ActiveRecord::Base
  include Versions::Auto
end

class Page < ActiveRecord::Base
  include Versions::Multi
  has_multiple :versions
end

Properties integration (status: beta)

You can get the same functionality as 'Transparent' by using the Property gem and storing properties in the version:

class Contact < ActiveRecord::Base
  include Versions::Multi
  has_multiple :versions

  include Property
  store_properties_in :version

  property do |p|
    p.string 'first_name', 'name'
  end
end

AfterCommit (status: beta)

Requiring 'versions' adds an 'after_commit' method to your models. The code in the after_commit block will only be executed if the top-most transaction succeeds (after the database commit). Example:

class Document < ActiveRecord::Base
  include Versions::AfterCommit
  after_save :save_file

  def save_file
    if @file
      after_commit do
        # write file to disk
      end
    end
  end
end

Attachment (status: beta)

Enable file attachments linked to versions. The attachments are shared between versions and deleted when no more versions are using them. Example:

# Mock a document class with many versions
class Document < ActiveRecord::Base
  include Versions::Multi
  has_multiple :versions

  include Versions::Attachment
  store_attachments_in :version, :attachment_class => 'Attachment'
end

Testing Gotcha

If you are testing your application with AfterCommit, you should note that the 'after_commit' code will *NEVER BE EXECUTED* if you have enabled transactional fixtures. You can fix this by disabling transactional fixtures in the tests where you need the after_commit code to execute (save file).

class DocumentTest < Test::Unit::TestCase
  self.use_transactional_fixtures = false

  # ...
end