0.03
Repository is archived
No commit activity in last 3 years
No release in over 3 years
DataMapper plugin enabling simple versioning of models
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Development

~> 1.6.4
~> 0.9.2
~> 1.3.2

Runtime

~> 1.2.0
 Project Readme

dm-is-versioned¶ ↑

DataMapper plugin enabling simple versioning of models.

When a model is versioned, and updated, instead of the previous version being lost in the mists of time, it is saved in a subsidiary table, so that it can be restored later if needed.

Please Note! this gem behaves differently to how AR’s :acts_as_versioned works. There is currently no multi version storage possible.

Installation¶ ↑

Stable¶ ↑

Install the dm-is-versioned gem.

$ (sudo)? gem install dm-is-versioned

Edge¶ ↑

Download or clone dm-is-versioned from Github.

$ cd /path/to/dm-is-versioned

$ rake install            # will install dm-is-versioned

Getting started¶ ↑

To start using this gem, just require dm-is-versioned in your app.

Lets say we have a Post class, and we want to retain the previous version of a post. Just do this:

class Post
  include DataMapper::Resource

  property :id,         Serial
  property :title,      String
  property :body,       Text
  property :updated_at, DateTime

  is_versioned :on => :updated_at

  ## this syntax also works
  # is :versioned, :on => :updated_at

end

That simple snippet will automatically create a second Post::Version model and a (post_versions) table in your DB when you auto migrate or auto upgrade:

Post.auto_migrate! # => will run auto_migrate! on Post::Version, too
Post.auto_upgrade! # => will run auto_upgrade! on Post::Version, too

# or
DataMapper.auto_migrate! # => will run auto_migrate! on Post::Version, too
DataMapper.auto_upgrade! # => will run auto_upgrade! on Post::Version, too

# don't forget to require 'dm-migrations' before you migrate.

OK, now that we have a versioned model, let’s see what we can do with it.

Usage¶ ↑

We start with creating a new Post:

post = Post.create(:title => 'A versioned Post title', :body => "A versioned Post body")
# automatically saved

When we create this Post, no secondary version is created.

The versioning only takes place when we update our Post:

post.title = "An updated & versioned Post title"
post.save

In the Post::Version (post_versions) table we would now find the previous version of the Post.

This is how it would look like:

# db.post table
---------------------------------------------------------------------------------------
| id | title                                | body                       | updated_at |
---------------------------------------------------------------------------------------
| 1 | 'An updated & versioned Post title'   | 'A versioned Post body'    | DateTime   |

# db.post_versions table
---------------------------------------------------------------------------------------
| id | title                                | body                       | updated_at |
---------------------------------------------------------------------------------------
| 1 | 'A versioned Post title'              | 'A versioned Post body'    | DateTime   |

#versions¶ ↑

Once you have a versioned model, you can retrieve the previous version, like this:

old_post = post.versions.first
  => #<Post::Version @id=1 @title="A versioned Post title" @body=... @updated_at=...>

Please Note! that the #versions method returns an array by default.

That’s basically what dm-is-versioned does.

Gotchas¶ ↑

Now there are some gotcha’s that might not be entirely obvious to everyone, so let’s clarify them here.

Make sure the versioned trigger has a value¶ ↑

In this type of scenario:

class Post
  <snip...>
  property :updated_at, DateTime

  is_versioned :on => :updated_at
end

You must ensure that the versioned trigger always has a value, either through:

# using the dm-timestamps gem, which automatically updates the :updated_at attribute
timestamps :at

# or a callback method, that updates the value before save
before(:save) { self.updated_at = Time.now }

Without this, things just don’t work.

Ensure you use dm-migrations gem¶ ↑

The post_versions table is NOT created unless you migrate your models through:

DataMapper.auto_migrate! / Post.auto_migrate!
DataMapper.auto_upgrade! / Post.auto_upgrade!

That’s about it.

Errors / Bugs¶ ↑

If something is not behaving intuitively, it is a bug, and should be reported. Report it here: datamapper.lighthouseapp.com/

TODOs¶ ↑

  • Make it work more like AR’s :acts_as_versioned plugin, with support for multiple versions and so on.

  • Enable replacing a current version with an old version.

  • Anything else missing?

Note on Patches/Pull Requests¶ ↑

  • Fork the project.

  • Make your feature addition or bug fix.

  • Add tests for it. This is important so we don’t break it in a future version unintentionally.

  • Commit, do not mess with rakefile, version, or history.

    • (if you want to have your own version, that is fine but bump version in a commit by itself we can ignore when we pull)

  • Send us a pull request. Bonus points for topic branches.

Copyright © 2011 Timothy Bennett. Released under the MIT License.

See LICENSE for details.

Credits¶ ↑

Credit also goes to these contributors.