revisions
Revisions provides a simple, wordpress-like, interface for tracking revisions to a model within a single table. It’s a bit rudimentary now, but I hope to add to it as necessary.
The basics:
-
Stores drafts, published items, and revisions
*
INSTALLATION
sudo gem install revisions –source gemcutter.org
then add to environment.rb config.gem ‘revisions’, :source => ‘gemcutter.org’
USAGE
The gem is a bit rigid at the moment, so you’ll need to setup two columns for it to use:
t.string :status # draft, published, revision t.integer :revision_of # Foreign Key that tracks what a model is revising.
You may also want to index these fields.
Once your models are setup, need to declare revisions within any model you intend to track. ie.
class Response < ActiveRecord::Base has_revisions end
You can also declare variables that you DON’T want to track (like a slug that has to be unique on the table, publication date, etc.)
class Response < ActiveRecord::Base has_revisions :ignore => [‘published_at’, ‘slug’] end
In addition to the variables you declare, revisions will ignore the status, id, revision_of, and created_at fields.
Now you’re all set to save and apply revisions. Revisions exposes three methods: latest_revision, pending_revisions?, save_revision and apply_revision.
latest_revision:
-
returns the latest revision
pending_revisions:
-
returns true if there are revisions with a more recent updated_at than the model.
save_revision:
-
Saves a copy of your model (a revision) in the same table
-
OG model doesn’t change, so all associations are intact
-
Behaves like standard ActiveRecord save (ie. returns true/false if it saves succesfully and creates an errors array if not)
-
can be called with bang (save_revision!) to throw an exception if it doesn’t save.
apply_revision
-
If called without params, maps the latest revision onto the model, but DOES NOT SAVE.
-
If called with a revision, maps that revision, but doesn’t save
-
if called with bang (apply_revision!), maps a revision AND saves
How about some examples.
Saving a Revision:
response = Response.create(=> ‘donkey’, :status => ‘published’) response.title = ‘monkey’ response.save_revision # => true response.revisions.size # => 1 response.pending_revision? # => true
save_revision doesn’t affect the original response
response.reload revision = response.latest_revision # => new response object. response.title # => ‘donkey’ revision.title # => ‘monkey’
apply_revision will affect the original response
response.apply_revision # => true response.title # => ‘monkey’
LIMITATIONS
There are a few things on the to-do list, among them:
-
There’s no way to prune revisions yet. But that’s coming ASAP.
-
Revisions assumes your model uses a standard rails Table Name (ie Response => Responses)
-
Revisions requires the status and revision_of columns (for now)
RELEASE NOTES
0.1.1
- Added updated_at to unrevised attributes to fix a bug in pending_revisions? on a revision.
0.3.1
- Added support for Rails 3.0 and 3.1
Author
Brian Hamman, hamman+github [ @ ] gmail.com