mongoid-history 0.0.9 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.rdoc CHANGED
@@ -42,6 +42,7 @@ Here is a quick example on how to use this plugin. For more details, please look
42
42
  :modifier_field => :modifier, # Adds "referened_in :modifier" to track who made the change. Default is :modifier
43
43
  :version_field => :version, # Adds "field :version, :type => Integer" to track current version. Default is :version
44
44
  :track_create => false, # Do you want to track document creation? Default is false
45
+ :track_destroy => false, # Do you want to track document destruction? Default is false
45
46
  end
46
47
 
47
48
  class Comment
@@ -56,8 +57,8 @@ Here is a quick example on how to use this plugin. For more details, please look
56
57
  embedded_in :post, :inverse_of => :comments
57
58
 
58
59
  # Track title and body for all comments, scope it to post (the parent)
59
- # Also track creation
60
- track_history :on => [:title, :body], :scope => :post, :track_create => true
60
+ # Also track creation and destruction
61
+ track_history :on => [:title, :body], :scope => :post, :track_create => true, :track_destroy => true
61
62
  end
62
63
 
63
64
  # The modifier can be specified as well
@@ -96,6 +97,12 @@ Here is a quick example on how to use this plugin. For more details, please look
96
97
 
97
98
  # redo last 3 versions
98
99
  comment.redo! @user, :last => 3
100
+
101
+ # delete post
102
+ post.destroy
103
+
104
+ # undelete post
105
+ post.undo! @user
99
106
 
100
107
  == Contributing to mongoid-history
101
108
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.9
1
+ 0.1.0
@@ -11,7 +11,8 @@ module Mongoid::History
11
11
  :modifier_field => :modifier,
12
12
  :version_field => :version,
13
13
  :scope => model_name,
14
- :track_create => false
14
+ :track_create => false,
15
+ :track_destroy => false,
15
16
  }
16
17
 
17
18
  options = default_options.merge(options)
@@ -42,6 +43,7 @@ module Mongoid::History
42
43
 
43
44
  before_update :track_update
44
45
  before_create :track_create if options[:track_create]
46
+ after_destroy :track_destroy if options[:track_destroy]
45
47
 
46
48
  Mongoid::History.trackable_classes ||= []
47
49
  Mongoid::History.trackable_classes << self
@@ -146,7 +148,15 @@ module Mongoid::History
146
148
  end
147
149
  end
148
150
 
149
- def history_tracker_attributes
151
+ def modified_attributes_for_destroy
152
+ @modified_attributes_for_destroy ||= attributes.inject({}) do |h, pair|
153
+ k,v = pair
154
+ h[k] = [nil, v]
155
+ h
156
+ end
157
+ end
158
+
159
+ def history_tracker_attributes(method)
150
160
  return @history_tracker_attributes if @history_tracker_attributes
151
161
 
152
162
  @history_tracker_attributes = {
@@ -155,7 +165,12 @@ module Mongoid::History
155
165
  :modifier => send(history_trackable_options[:modifier_field])
156
166
  }
157
167
 
158
- original, modified = transform_changes((new_record? ? modified_attributes_for_create : modified_attributes_for_update))
168
+ original, modified = transform_changes(case method
169
+ when :destroy then modified_attributes_for_destroy
170
+ when :create then modified_attributes_for_create
171
+ else modified_attributes_for_update
172
+ end)
173
+
159
174
  @history_tracker_attributes[:original] = original
160
175
  @history_tracker_attributes[:modified] = modified
161
176
  @history_tracker_attributes
@@ -165,7 +180,7 @@ module Mongoid::History
165
180
  return unless should_track_update?
166
181
  current_version = (self.send(history_trackable_options[:version_field]) || 0 ) + 1
167
182
  self.send("#{history_trackable_options[:version_field]}=", current_version)
168
- Mongoid::History.tracker_class.create!(history_tracker_attributes.merge(:version => current_version))
183
+ Mongoid::History.tracker_class.create!(history_tracker_attributes(:update).merge(:version => current_version, :action => "update"))
169
184
  clear_memoization
170
185
  end
171
186
 
@@ -173,7 +188,14 @@ module Mongoid::History
173
188
  return unless track_history?
174
189
  current_version = (self.send(history_trackable_options[:version_field]) || 0 ) + 1
175
190
  self.send("#{history_trackable_options[:version_field]}=", current_version)
176
- Mongoid::History.tracker_class.create!(history_tracker_attributes.merge(:version => current_version))
191
+ Mongoid::History.tracker_class.create!(history_tracker_attributes(:create).merge(:version => current_version, :action => "create"))
192
+ clear_memoization
193
+ end
194
+
195
+ def track_destroy
196
+ return unless track_history?
197
+ current_version = (self.send(history_trackable_options[:version_field]) || 0 ) + 1
198
+ Mongoid::History.tracker_class.create!(history_tracker_attributes(:destroy).merge(:version => current_version, :action => "destroy"))
177
199
  clear_memoization
178
200
  end
179
201
 
@@ -205,4 +227,4 @@ module Mongoid::History
205
227
  end
206
228
 
207
229
  end
208
- end
230
+ end
@@ -10,6 +10,7 @@ module Mongoid::History
10
10
  field :modified, :type => Hash
11
11
  field :original, :type => Hash
12
12
  field :version, :type => Integer
13
+ field :action, :type => String
13
14
  field :scope, :type => String
14
15
  referenced_in :modifier, :class_name => Mongoid::History.modifer_class_name
15
16
 
@@ -21,11 +22,21 @@ module Mongoid::History
21
22
  end
22
23
 
23
24
  def undo!(modifier)
24
- trackable.update_attributes!(undo_attr(modifier))
25
+ if action.to_sym == :destroy
26
+ class_name = association_chain[0]["name"]
27
+ restored = class_name.constantize.new(modified)
28
+ restored.save!
29
+ else
30
+ trackable.update_attributes!(undo_attr(modifier))
31
+ end
25
32
  end
26
33
 
27
34
  def redo!(modifier)
28
- trackable.update_attributes!(redo_attr(modifier))
35
+ if action.to_sym == :destroy
36
+ trackable.destroy
37
+ else
38
+ trackable.update_attributes!(redo_attr(modifier))
39
+ end
29
40
  end
30
41
 
31
42
  def undo_attr(modifier)
@@ -57,15 +68,16 @@ module Mongoid::History
57
68
  end
58
69
 
59
70
  def affected
60
- @affected ||= (modified.keys | original.keys).inject({}){ |h,k| h[k] = trackable.attributes[k]; h}
71
+ @affected ||= (modified.keys | original.keys).inject({}){ |h,k| h[k] =
72
+ trackable ? trackable.attributes[k] : modified[k]; h}
61
73
  end
62
74
 
63
75
  private
64
76
  def trackable_parents_and_trackable
65
- @trackable_parents_and_trackable ||= triverse_association_chain
77
+ @trackable_parents_and_trackable ||= traverse_association_chain
66
78
  end
67
79
 
68
- def triverse_association_chain
80
+ def traverse_association_chain
69
81
  chain = association_chain.dup
70
82
  doc = nil
71
83
  documents = []
@@ -80,4 +92,4 @@ private
80
92
  end
81
93
 
82
94
  end
83
- end
95
+ end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{mongoid-history}
8
- s.version = "0.0.9"
8
+ s.version = "0.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Aaron Qian", "Justin Grimes"]
12
- s.date = %q{2011-04-05}
12
+ s.date = %q{2011-05-13}
13
13
  s.description = %q{In frustration of Mongoid::Versioning, I created this plugin for tracking historical changes for any document, including embedded ones. It achieves this by storing all history tracks in a single collection that you define. (See Usage for more details) Embedded documents are referenced by storing an association path, which is an array of document_name and document_id fields starting from the top most parent document and down to the embedded document that should track history.
14
14
 
15
15
  This plugin implements multi-user undo, which allows users to undo any history change in any order. Undoing a document also creates a new history track. This is great for auditing and preventing vandalism, but it is probably not suitable for use cases such as a wiki.}
@@ -40,7 +40,7 @@ Gem::Specification.new do |s|
40
40
  s.homepage = %q{http://github.com/aq1018/mongoid-history}
41
41
  s.licenses = ["MIT"]
42
42
  s.require_paths = ["lib"]
43
- s.rubygems_version = %q{1.5.2}
43
+ s.rubygems_version = %q{1.5.3}
44
44
  s.summary = %q{history tracking, auditing, undo, redo for mongoid}
45
45
  s.test_files = [
46
46
  "spec/integration/integration_spec.rb",
@@ -16,7 +16,7 @@ describe Mongoid::History do
16
16
  field :rating
17
17
 
18
18
  embeds_many :comments
19
- track_history :on => [:title, :body]
19
+ track_history :on => [:title, :body], :track_destroy => true
20
20
  end
21
21
 
22
22
  class Comment
@@ -37,7 +37,7 @@ describe Mongoid::History do
37
37
 
38
38
  field :email
39
39
  field :name
40
- track_history :except => [:email]
40
+ track_history :except => [:email]
41
41
  end
42
42
  end
43
43
 
@@ -62,7 +62,6 @@ describe Mongoid::History do
62
62
  @comment.history_tracks.first.original.should == {}
63
63
  end
64
64
 
65
-
66
65
  it "should assign modifier" do
67
66
  @comment.history_tracks.first.modifier.should == @user
68
67
  end
@@ -74,12 +73,35 @@ describe Mongoid::History do
74
73
  it "should assign scope" do
75
74
  @comment.history_tracks.first.scope == "Post"
76
75
  end
76
+
77
+ it "should assign method" do
78
+ @comment.history_tracks.first.action == "create"
79
+ end
77
80
 
78
81
  it "should assign association_chain" do
79
82
  @comment.history_tracks.first.association_chain = [{:id => @post.id, :name => "Post"}, {:id => @comment.id, :name => "Comment"}]
80
83
  end
81
84
  end
82
85
 
86
+ describe "on destruction" do
87
+ it "should have two history track records in post" do
88
+ lambda {
89
+ @post.destroy
90
+ }.should change(HistoryTracker, :count).by(1)
91
+ end
92
+
93
+ it "should assign destroy on track record" do
94
+ @post.destroy
95
+ @post.history_tracks.last.action == "destroy"
96
+ end
97
+
98
+ it "should return affected attributes from track record" do
99
+ @post.destroy
100
+ @post.history_tracks.last.affected["title"] == "Test"
101
+ end
102
+
103
+ end
104
+
83
105
  describe "on update non-embedded" do
84
106
  it "should create a history track if changed attributes match tracked attributes" do
85
107
  lambda {
@@ -99,6 +121,11 @@ describe Mongoid::History do
99
121
  "title" => "Another Test"
100
122
  }
101
123
  end
124
+
125
+ it "should assign method field" do
126
+ @post.update_attributes(:title => "Another Test")
127
+ @post.history_tracks.first.action.should == "update"
128
+ end
102
129
 
103
130
  it "should assign original fields" do
104
131
  @post.update_attributes(:title => "Another Test")
@@ -221,6 +248,12 @@ describe Mongoid::History do
221
248
  @post.reload
222
249
  @post.title.should == "Test"
223
250
  end
251
+
252
+ it "should undo destruction" do
253
+ @post.destroy
254
+ @post.history_tracks.where(:version => 1).first.undo!(@user)
255
+ Post.find(@post.id).title.should == "Test"
256
+ end
224
257
 
225
258
  it "should create a new history track after undo" do
226
259
  @post.update_attributes(:title => "Test2")
@@ -245,6 +278,15 @@ describe Mongoid::History do
245
278
 
246
279
  @post.title.should == @post2.title
247
280
  end
281
+
282
+ it "should be destroyed after undo and redo" do
283
+ @post.destroy
284
+ @track = @post.history_tracks.where(:version => 1).first
285
+ @track.undo!(@user)
286
+ @track.redo!(@user)
287
+ Post.where(:_id => @post.id).first == nil
288
+ end
289
+
248
290
  end
249
291
 
250
292
  describe "embedded" do
@@ -43,7 +43,8 @@ describe Mongoid::History::Trackable do
43
43
  :version_field => :version,
44
44
  :scope => :my_model,
45
45
  :except => ["created_at", "updated_at", "version", "modifier_id", "_id", "id"],
46
- :track_create => false
46
+ :track_create => false,
47
+ :track_destroy => false,
47
48
  }
48
49
  end
49
50
 
@@ -64,6 +65,10 @@ describe Mongoid::History::Trackable do
64
65
  MyModel.new.private_methods.collect(&:to_sym).should include(:track_create)
65
66
  end
66
67
 
68
+ it "should define callback function #track_destroy" do
69
+ MyModel.new.private_methods.collect(&:to_sym).should include(:track_destroy)
70
+ end
71
+
67
72
  it "should define #history_trackable_options" do
68
73
  MyModel.history_trackable_options.should == @expected_option
69
74
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: mongoid-history
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.9
5
+ version: 0.1.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Aaron Qian
@@ -11,7 +11,7 @@ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
 
14
- date: 2011-04-05 00:00:00 -07:00
14
+ date: 2011-05-13 00:00:00 -07:00
15
15
  default_executable:
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
@@ -170,7 +170,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
170
170
  requirements:
171
171
  - - ">="
172
172
  - !ruby/object:Gem::Version
173
- hash: 2391533013898856093
173
+ hash: -1260875336228097140
174
174
  segments:
175
175
  - 0
176
176
  version: "0"
@@ -183,7 +183,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
183
183
  requirements: []
184
184
 
185
185
  rubyforge_project:
186
- rubygems_version: 1.5.2
186
+ rubygems_version: 1.5.3
187
187
  signing_key:
188
188
  specification_version: 3
189
189
  summary: history tracking, auditing, undo, redo for mongoid