Module: Memories
- Defined in:
- lib/memories/base.rb,
lib/memories/annotation.rb,
lib/memories/attachment.rb,
lib/memories/versions_proxy.rb,
lib/memories/milestones_proxy.rb
Overview
Simply “include Memories” in your CouchRest::Model::Base derived classes to add versioning to your document.
Defined Under Namespace
Modules: ClassMethods Classes: Annotation, Attachment, MilestoneProxy, MilestonesProxy, VersionProxy, VersionsProxy
Constant Summary collapse
- VERSION_REGEX =
:nodoc:
/(?:rev-)?(\d+)-[a-zA-Z0-9]+/
Class Method Summary collapse
Instance Method Summary collapse
-
#attachments_to_forget ⇒ Object
Returns a list of attachments it should not version.
-
#attachments_to_remember ⇒ Object
Returns a list of attachments it should remember.
-
#current_version ⇒ Object
Returns a simple version number (integer) corresponding to the current revision.
-
#latest_milestone ⇒ Object
Returns the metadata (version, annotations) for the latest milestone created.
-
#logical_revision ⇒ Object
When you soft revert a document, you can ask what the logical revision of it is.
-
#logical_version_number ⇒ Object
When you soft revert a document, you can ask what the logical version number of it is.
-
#milestone!(&block) ⇒ Object
Flag the current version as a milestone.
-
#milestone? ⇒ Boolean
Returns true if this instance represents a milestone.
-
#milestone_commit? ⇒ Boolean
Returns true if this instance is the version made right after a milestone, to denote the previous version as a milestone.
-
#milestones ⇒ Object
As of version 0.2.0, Memories also supports milestones.
-
#previous_version ⇒ Object
Shortcut for: my_doc.current_version - 1.
-
#revert_to(version) ⇒ Object
Same as #revert_to!, except that it doesn’t save.
-
#revert_to!(version) ⇒ Object
Revert the document to a specific version and save.
-
#revert_to_milestone(n) ⇒ Object
Same as #revert_to_milestone!, except it doesn’t save.
-
#revert_to_milestone!(n) ⇒ Object
Revert to a given milestone and save.
-
#rollback ⇒ Object
Same as #rollback!, but doesn’t save.
-
#rollback! ⇒ Object
Revert to the previous version, and resave the document.
-
#rollback_to_latest_milestone ⇒ Object
Same as #rollback_to_latest_milestone, but doesn’t save.
-
#rollback_to_latest_milestone! ⇒ Object
Reverts to the latest milestone.
- #save_with_destroying_logical_version_and_revision(options = {}) ⇒ Object
- #save_with_destroying_logical_version_and_revision! ⇒ Object
-
#version_id(version_num) ⇒ Object
Retrieve the entire revision number, given an integer.
-
#version_number(version_id) ⇒ Object
Retrieve the version number, given a revision id.
-
#versions ⇒ Object
Provides array-like and hash-like access to the versions of your document.
Class Method Details
.included(base) ⇒ Object
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/memories/base.rb', line 3 def self.included(base) base.property(:milestone_memories) do |milestone_memory| milestone_memory.property :version milestone_memory.property :annotations, Memories::Annotation, :init_method => proc { |value| a = Memories::Annotation.new value.keys.each do |key| a.send key, value[key] end a } end base.before_update :add_version_attachment base.after_save :decode_attachments base.send :extend, ClassMethods base.alias_method_chain :save, :destroying_logical_version_and_revision base.alias_method_chain :save!, :destroying_logical_version_and_revision end |
Instance Method Details
#attachments_to_forget ⇒ Object
Returns a list of attachments it should not version
140 141 142 143 144 145 146 147 148 |
# File 'lib/memories/base.rb', line 140 def return [] unless self.class. (self.database.get(self.id)["_attachments"] || {}).keys.reject do |a| a.match(VERSION_REGEX) || (self.class..map { || a.match }.inject(false) {|b, sum| sum || b}) end end |
#attachments_to_remember ⇒ Object
Returns a list of attachments it should remember.
129 130 131 132 133 134 135 136 137 |
# File 'lib/memories/base.rb', line 129 def return [] unless self.class. (self.database.get(self.id)["_attachments"] || {}).keys.reject do |a| a.match(VERSION_REGEX) || !(self.class..map { || a.match }.inject(false) {|b, sum| sum || b}) end end |
#current_version ⇒ Object
Returns a simple version number (integer) corresponding to the current revision. For example, suppose the current revision (_rev) is: “4-jkfdlsi9432943wklrejwalr94302”.
my_doc.current_version #==> 4
225 226 227 |
# File 'lib/memories/base.rb', line 225 def current_version version_number rev end |
#latest_milestone ⇒ Object
Returns the metadata (version, annotations) for the latest milestone created.
314 315 316 |
# File 'lib/memories/base.rb', line 314 def latest_milestone self.milestones.last end |
#logical_revision ⇒ Object
When you soft revert a document, you can ask what the logical revision of it is. For example, suppose you soft revert a document with 10 versions to version 2.
@doc.revert_to 2
When you ask the logical revision, you’ll receive the revision number of version 2:
@doc.logical_revision #==> 'rev-2-kfdlsa432890432890432'
However, as soon as you save the document, the logical_revision will simply mirror the actual revision
@doc.save
@doc.rev #==> '11-qwerty1234567890'
@doc.logical_revision #==> 'rev-11-qwerty1234567890'
337 338 339 |
# File 'lib/memories/base.rb', line 337 def logical_revision @logical_revision || "rev-" + self.rev end |
#logical_version_number ⇒ Object
When you soft revert a document, you can ask what the logical version number of it is. For example, suppose you soft revert a document with 10 versions to version 2.
@doc.revert_to 2
When you ask the logical version number, you’ll receive 2:
@doc.logical_version_number #==> 2
However, as soon as you save the document, the logical_revision will simply mirror the actual revision
@doc.save
@doc.current_version #==> 11
@doc.logical_version_number #==> 11
350 351 352 |
# File 'lib/memories/base.rb', line 350 def logical_version_number @logical_version_number || self.current_version end |
#milestone!(&block) ⇒ Object
Flag the current version as a milestone. You can optionally annotate the milestone by passing a do block to the method.
some_article.milestone! do
notes "Passed first round of editing."
approved_by "Joe the editor."
end
You may annotate with whatever properties you desire. “notes” and “approved_by” were simply examples.
247 248 249 250 251 252 |
# File 'lib/memories/base.rb', line 247 def milestone!(&block) annotations = Memories::Annotation.new annotations.instance_eval(&block) if block self.milestone_memories << {:version => self.rev, :annotations => annotations.to_hash} self.save end |
#milestone? ⇒ Boolean
Returns true if this instance represents a milestone
319 320 321 |
# File 'lib/memories/base.rb', line 319 def milestone? self.milestones.collect(&:version_number).include? self.logical_version_number end |
#milestone_commit? ⇒ Boolean
Returns true if this instance is the version made right after a milestone, to denote the previous version as a milestone.
324 325 326 |
# File 'lib/memories/base.rb', line 324 def milestone_commit? self.milestones.collect(&:version_number).include? self.logical_version_number - 1 end |
#milestones ⇒ Object
As of version 0.2.0, Memories also supports milestones. Milestones are special versions that you want to flag in some way. For example, suppose you were creating a content management system, and every time someone publishes an article to the website, you want to flag the version they published as a milestone.
class Article < CouchRest::Model::Base
include Memories
use_database SOME_DATABASE
property :title
property :author
property :body
def publish!
# .... publishing logic
end
end
a = Article.create(
:title => "Memories gem makes versioning simple",
:author => "moonmaster9000",
:body => <<-ARTICLE
Check it out at http://github.com/moonmaster9000/memories
ARTICLE
)
a.save
a.publish!
a.current_version #==> 1
a.milestone! do
name "First publish."
notes "Passed all relevant editing. Signed off by moonmaster10000"
end
Notice that we annotated our milestone; we gave it a name, and some notes. You can annotate with whatever properties you desire. The annotation do block is entirely optional. Now that we’ve created a milestone, let’s inspect it via the ‘milestones` array:
a.milestones.count #==> 1
a.milestones.last.version # ==> 1
a.milestones.last.version # ==> 1
a.milestones.last.annotations.name ==> "First publish."
a.milestones.last.annotations.notes ==> "Passed all relevant editing. Signed off by moonmaster10000"
Now, let’s imagine that we’ve made some more edits / saves to the document, but they don’t get approved. Now we want to revert to the version the document was at at the first milestone. How do we do that? Simple!
a.revert_to_milestone! 1
And now our document properties are back to the where they were when we first published the document.
If you want to access the data from a milestone, simply use the “data” method:
a.milestones.first.data.title #==> returns the "title" attribute on the first milestone
a.milestones.each do |m|
puts "Version: " + m.version
puts "Title: " + m.data.title
end
309 310 311 |
# File 'lib/memories/base.rb', line 309 def milestones @milestones_proxy ||= MilestonesProxy.new self end |
#previous_version ⇒ Object
Shortcut for:
my_doc.current_version - 1
218 219 220 |
# File 'lib/memories/base.rb', line 218 def previous_version current_version - 1 end |
#revert_to(version) ⇒ Object
Same as #revert_to!, except that it doesn’t save.
160 161 162 163 |
# File 'lib/memories/base.rb', line 160 def revert_to(version) revert version self end |
#revert_to!(version) ⇒ Object
Revert the document to a specific version and save. You can provide either a complete revision number (“1-u54abz3948302sjjej3jej300rj”, or “rev-1-u54abz3948302sjjej3jej300rj”) or simply a number (e.g, 1, 4, 100, etc.).
my_doc.revert_to! 3 # ==> would revert your document "my_doc" to version 3.
154 155 156 157 |
# File 'lib/memories/base.rb', line 154 def revert_to!(version) revert version, :hard self end |
#revert_to_milestone(n) ⇒ Object
Same as #revert_to_milestone!, except it doesn’t save.
185 186 187 188 |
# File 'lib/memories/base.rb', line 185 def revert_to_milestone(n) verify_milestone_exists n self.revert_to self.milestones[n.to_i-1].version end |
#revert_to_milestone!(n) ⇒ Object
Revert to a given milestone and save. Milestones are stored in the .milestones array. Reverting to milestone “n” reverts to milestone represented in the nth element in the milestones array.
179 180 181 182 |
# File 'lib/memories/base.rb', line 179 def revert_to_milestone!(n) verify_milestone_exists n self.revert_to! self.milestones[n.to_i-1].version end |
#rollback ⇒ Object
Same as #rollback!, but doesn’t save.
166 167 168 |
# File 'lib/memories/base.rb', line 166 def rollback self.revert_to self.previous_version end |
#rollback! ⇒ Object
Revert to the previous version, and resave the document. Shortcut for:
my_doc.revert_to! my_doc.previous_version
172 173 174 |
# File 'lib/memories/base.rb', line 172 def rollback! self.revert_to! self.previous_version end |
#rollback_to_latest_milestone ⇒ Object
Same as #rollback_to_latest_milestone, but doesn’t save.
191 192 193 |
# File 'lib/memories/base.rb', line 191 def rollback_to_latest_milestone self.revert_to_milestone self.milestones.count end |
#rollback_to_latest_milestone! ⇒ Object
Reverts to the latest milestone. Shortcut for:
my_doc.revert_to_milestone! my_doc.milestones.count
197 198 199 |
# File 'lib/memories/base.rb', line 197 def rollback_to_latest_milestone! self.revert_to_milestone! self.milestones.count end |
#save_with_destroying_logical_version_and_revision(options = {}) ⇒ Object
354 355 356 357 358 |
# File 'lib/memories/base.rb', line 354 def (={}) @logical_version_number = nil @logical_revision = nil () end |
#save_with_destroying_logical_version_and_revision! ⇒ Object
360 361 362 363 364 |
# File 'lib/memories/base.rb', line 360 def @logical_version_number = nil @logical_revision = nil end |
#version_id(version_num) ⇒ Object
Retrieve the entire revision number, given an integer. For example, suppose my doc has 5 versions.
my_doc.version_id 4 #==> "rev-4-74fj838r838fhjkdfklasdjrieu4839493"
204 205 206 |
# File 'lib/memories/base.rb', line 204 def version_id(version_num) self["_attachments"].keys.select {|a| a.match /^rev-#{version_num}-.*$/}.first if self["_attachments"] end |
#version_number(version_id) ⇒ Object
Retrieve the version number, given a revision id. For example,
my_doc.version_number "rev-5-kjfldsjaiu932489023rewar" #==> 5
my_doc.version_number "4-jkfldsjli3290843029irelajfldsa" # ==> 4
212 213 214 |
# File 'lib/memories/base.rb', line 212 def version_number(version_id) version_id.gsub(VERSION_REGEX, '\1').to_i end |
#versions ⇒ Object
Provides array-like and hash-like access to the versions of your document.
@doc.versions[1] # ==> returns version 1 of your document
@doc.versions['rev-1-kjfdsla3289430289432'] # ==> returns version 1 of your document
@doc.versions[5..20] # ==> returns versions 5 through 20 of your document
@doc.versions.count # ==> returns the number of versions of your document
@doc.versions.last # ==> returns the latest version of your document
@doc.versions.first # ==> returns the first version of your document
236 237 238 |
# File 'lib/memories/base.rb', line 236 def versions @versions ||= VersionsProxy.new self end |