A simple Mongoid 3 and 4 versioning system that works with embedded documents.
Tracking document changes can be really important to a lot of systems, unfortunately all of the Mongoid versioning plugins either only work with Mongoid 2.x, don't handle embedded document changes, or worse, just don't work. Mongoid::Delorean
solves those problems.
Mongoid::Delorean
is a simple plugin that does just what it sets out to do. It stores each version of your document as you make changes and then allows you to revert to earlier versions of the document.
If this wasn't great already, Mongoid::Delorean
will even track changes made to any embedded documents, or documents that those embedded documents may have, and so on.
Add this line to your application's Gemfile:
gem 'mongoid_delorean'
And then execute:
$ bundle
Or install it yourself as:
$ gem install mongoid_delorean
Using Mongoid::Delorean is very simple. Just include the Mongoid::Delorean::Trackable
module into the Mongoid::Document
you want to track. There is no need to include it in embedded documents, the parent document will handle that for you.
Now, when you save, or update, the parent (or any of the embedded documents) a new version will be saved for you.
class Article
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::Delorean::Trackable
field :name, type: String
field :summary, type: String
embeds_many :pages
end
class Page
include Mongoid::Document
include Mongoid::Timestamps
field :name, type: String
embedded_in :article, inverse_of: :pages
embeds_many :sections
end
class Section
include Mongoid::Document
include Mongoid::Timestamps
field :name, type: String
field :body, type: String
embedded_in :page, inverse_of: :sections
end
a = Article.create(name: "Article 1")
a.version # => 1
page = a.pages.create(name: "Page 1")
a.version # => 2
page.update_attributes(name: "The 1st Page")
a.version # => 3
a.revert! # revert to the last version
page.reload
page.name # => "Page 1"
a.version # => 4
page.sections.create(name: "Section 1")
a.version # => 5
a.revert!(2) # revert to version 2
page.reload
a.version # => 6
page.name # => "Page 1"
page.sections.size # => 0
a.versions.size # => 6
If you don't want to track changes you can wrap it with without_history_tracking
:
a = Article.create(name: "Article 1")
a.without_history_tracking do
a.update_attributes(name: "The Article 1")
end
a.version # => 1
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Write your tests
- Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request
- Mark Bates
- Nick Muerdter
- Felipe Rodrigues
- Felipe Rodrigues de Almeida