Undo

Build Status Coverage Status Code Climate Gemnasium Build Status Gem Version

The Undo restores previous object state.
It stores the object state before the mutation and allows to restore this state later.

Lightweight, modular and very flexible library that works as with Rails, as with plain Ruby. No specific persistence required: store data as it suites you.

The Undo uses plugable adapters for storage such as Redis, RailsCache. And serializers such as ActiveModel for example. Simple interface makes it easy to implement new adapters or tweak existing.

Most of adapters and serializers have no external dependencies and can be used with similary quaking objects.

Contents

  1. Installation
  2. Requirements
  3. Usage
    1. Undo operation
    2. Configuration options
    3. In place configuration
    4. Pass through options
    5. Utils
  4. Contacts
  5. Compatibility
  6. Contributing
  7. Copyright

Installation

Add this line to your application's Gemfile:

gem 'undo'

And then execute:

$ bundle

Or install it yourself as:

$ gem install undo

Requirements

  1. Ruby 1.9 or above
  2. gem virtus ~> 1.0

Usage

Undo operation

uuid = Undo.store object

# ... 
# do something destructive
# ...

Undo.restore uuid

That is basically it :)

To use something more advanced than plain memory storage and pass through serializer, configure the Undo:

Undo.configure do |config|
  config.storage = Undo::Storage::RailsCache.new
  config.serializer = Undo::Serializer::ActiveModel.new
end

It allows to serialize and deserialize ActiveRecord models (and POROs after implementing the #attributes method) and store it to Rails cache. See those gems documentation for more details:

There are more adapters. Read about them in configuration chapter below.

When storage does not garbage collect old records, call

Undo.delete uuid

to manually delete related data in storage. It accepts the same options as store/restore.

UUID

UUID is a uniq key used by the Undo to store and retrieve data. It is generated automatically, but it is possible to either provide custom uuid or custom uuid generator.

# use generated uuid
uuid = Undo.store object
Undo.restore uuid

# manually specify uuid
uuid = "uniq identifier"
Undo.store object, uuid: uuid
Undo.restore uuid

# specify uuid generator in place
uuid = Undo.store object, uuid_generator: ->(object) { "#{object.class.name}_#{object.id}" }
Undo.restore uuid

By default uuids are generated by SecureRandom.uuid. The generator set by uuid_generator option which may be set in place as shown above or in global configuration (see below).

Configuration options

Storage

The storage option is responsible of defining a storage adapter that can store, fetch and delete object state from storage.

Adapter must implement store(uuid, object, options), fetch(uuid, options) and optionally delete(uuid, options) methods. Naming follows ruby Hash interface.

Currently available storage adapters:

Check the documentation on Github for current list of available storage adapters.

Serializer

To convert objects to hashes that can be processed by storage adapters and backward, serializer is used:

Undo.configure do |config|
  config.serializer = CustomSerializer.new
end

Serializer must implement serialize(object, options) and deserialize(object, options) methods.

Currently available serializers:

Check the documentation on Github for current list of available serializers.

Serializer could return any type of object, Hash is not forced. But in this case compatible storage adapter should be used.

UUID generator

uuid_generator option allows to setup custom uuid generator:

Undo.configure do |config|
  config.uuid_generator = ->(object) { "#{object.class.name}_#{object.id}" }
end

By default it is using SecureRandom.uuid.

In place configuration

Any configuration option from previous chapter can be applied in place for a given operation.

For example to restore object from another storage, the storage option may be used in place:

Undo.restore uuid, storage: AnotherStorage.new

To use custom serializer or deserializer use serializer option:

Undo.store post, serializer: PostSerializer.new(post)
Undo.restore uuid, serializer: PostDeserializer.new(options)

and so on.

Pass through options

Any option, that is not recognized by the Undo as configuration option, will be bypass to the serializer and storage adapter:

Undo.store post, include: :comments, expires_in: 1.hour

Same applies for #restore and #delete methods.

Utils

Contacts

Have questions or recommendations? Contact me via [email protected] Found a bug or have enhancement request? You are welcome at Github bugtracker

Compatibility

tested with Ruby

  • 2.1
  • 2.0
  • 1.9.3
  • ruby-head
  • rbx
  • jruby-19mode
  • jruby-head

See build history

Contributing

  1. Fork repository
  2. Create feature branch (git checkout -b my-new-feature)
  3. Commit changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request on Github

Copyright © 2014 Alexander Paramonov. Released under the MIT License. See the LICENSE file for further details.