mongoid-history 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,118 @@
1
+ Contributing to Mongoid-History
2
+ ===============================
3
+
4
+ Mongoid-History is work of [many of contributors](https://github.com/intridea/mongoid-history/graphs/contributors). You're encouraged to submit [pull requests](https://github.com/intridea/mongoid-history/pulls), [propose features, ask questions and discuss issues](https://github.com/intridea/mongoid-history/issues).
5
+
6
+ #### Fork the Project
7
+
8
+ Fork the [project on Github](https://github.com/intridea/mongoid-history) and check out your copy.
9
+
10
+ ```
11
+ git clone https://github.com/contributor/mongoid-history.git
12
+ cd mongoid-history
13
+ git remote add upstream https://github.com/intridea/mongoid-history.git
14
+ ```
15
+
16
+ #### Create a Topic Branch
17
+
18
+ Make sure your fork is up-to-date and create a topic branch for your feature or bug fix.
19
+
20
+ ```
21
+ git checkout master
22
+ git pull upstream master
23
+ git checkout -b my-feature-branch
24
+ ```
25
+
26
+ #### Bundle Install and Test
27
+
28
+ Ensure that you can build the project and run tests.
29
+
30
+ ```
31
+ bundle install
32
+ bundle exec rake
33
+ ```
34
+
35
+ #### Write Tests
36
+
37
+ Try to write a test that reproduces the problem you're trying to fix or describes a feature that you want to build. Add to [spec/mongoid-history](spec/mongoid-history).
38
+
39
+ We definitely appreciate pull requests that highlight or reproduce a problem, even without a fix.
40
+
41
+ #### Write Code
42
+
43
+ Implement your feature or bug fix.
44
+
45
+ Ruby style is enforced with [Rubocop](https://github.com/bbatsov/rubocop), run `bundle exec rubocop` and fix any style issues highlighted.
46
+
47
+ Make sure that `bundle exec rake` completes without errors.
48
+
49
+ #### Write Documentation
50
+
51
+ Document any external behavior in the [README](README.md).
52
+
53
+ #### Update Changelog
54
+
55
+ Add a line to [CHANGELOG](CHANGELOG.md) under *Next Release*. Make it look like every other line, including your name and link to your Github account.
56
+
57
+ #### Commit Changes
58
+
59
+ Make sure git knows your name and email address:
60
+
61
+ ```
62
+ git config --global user.name "Your Name"
63
+ git config --global user.email "contributor@example.com"
64
+ ```
65
+
66
+ Writing good commit logs is important. A commit log should describe what changed and why.
67
+
68
+ ```
69
+ git add ...
70
+ git commit
71
+ ```
72
+
73
+ #### Push
74
+
75
+ ```
76
+ git push origin my-feature-branch
77
+ ```
78
+
79
+ #### Make a Pull Request
80
+
81
+ Go to https://github.com/contributor/mongoid-history and select your feature branch. Click the 'Pull Request' button and fill out the form. Pull requests are usually reviewed within a few days.
82
+
83
+ #### Rebase
84
+
85
+ If you've been working on a change for a while, rebase with upstream/master.
86
+
87
+ ```
88
+ git fetch upstream
89
+ git rebase upstream/master
90
+ git push origin my-feature-branch -f
91
+ ```
92
+
93
+ #### Update CHANGELOG Again
94
+
95
+ Update the [CHANGELOG](CHANGELOG.md) with the pull request number. A typical entry looks as follows.
96
+
97
+ ```
98
+ * [#123](https://github.com/intridea/mongoid-history/pull/123): Reticulated splines - [@contributor](https://github.com/contributor).
99
+ ```
100
+
101
+ Amend your previous commit and force push the changes.
102
+
103
+ ```
104
+ git commit --amend
105
+ git push origin my-feature-branch -f
106
+ ```
107
+
108
+ #### Check on Your Pull Request
109
+
110
+ Go back to your pull request after a few minutes and see whether it passed muster with Travis-CI. Everything should look green, otherwise fix issues and amend your commit as described above.
111
+
112
+ #### Be Patient
113
+
114
+ It's likely that your change will not be merged and that the nitpicky maintainers will ask you to do more, or fix seemingly benign problems. Hang on there!
115
+
116
+ #### Thank You
117
+
118
+ Please do know that we really appreciate and value your time and work. We love you, really.
data/Gemfile CHANGED
@@ -1,16 +1,12 @@
1
- source "http://rubygems.org"
2
-
3
- gem "easy_diff"
4
- gem "mongoid", ">= 3.0"
5
- gem "activesupport"
6
-
7
- group :test do
8
- gem "rspec", ">= 2.11.0"
9
- gem "bundler", ">= 1.0.0"
10
- end
11
-
12
- group :development do
13
- gem 'rubocop', '~> 0.15.0'
14
- gem "yard"
15
- gem "jeweler"
16
- end
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ case version = ENV['MONGOID_VERSION'] || '~> 4.0'
6
+ when /4/
7
+ gem 'mongoid', '~> 4.0'
8
+ when /3/
9
+ gem 'mongoid', '~> 3.1'
10
+ else
11
+ gem 'mongoid', version
12
+ end
@@ -1,20 +1,20 @@
1
- Copyright (c) 2011 Aaron Qian
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ Copyright (c) 2011 Aaron Qian
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,309 +1,312 @@
1
- mongoid-history
2
- ===============
3
-
4
- [![Build Status](https://secure.travis-ci.org/aq1018/mongoid-history.png?branch=master)](http://travis-ci.org/aq1018/mongoid-history)
5
- [![Code Climate](https://codeclimate.com/github/aq1018/mongoid-history.png)](https://codeclimate.com/github/aq1018/mongoid-history)
6
-
7
- Mongoid-history tracks historical changes for any document, including embedded ones. It achieves this by storing all history tracks in a single collection that you define. 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.
8
-
9
- This gem also 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 is probably not suitable for use cases such as a wiki.
10
-
11
- Stable Release
12
- --------------
13
-
14
- You're reading the documentation the 0.4.x release that supports Mongoid 3.x. For 2.x compatible mongoid-history, please use a 0.2.x version from the [2.x-stable branch](https://github.com/aq1018/mongoid-history/tree/2.4-stable).
15
-
16
- Install
17
- -------
18
-
19
- This gem supports Mongoid 3.x on Ruby 1.9.3 only. Add it to your `Gemfile` or run `gem install mongoid-history`.
20
-
21
- ```ruby
22
- gem 'mongoid-history'
23
- ```
24
-
25
- Usage
26
- -----
27
-
28
- **Create a history tracker**
29
-
30
- Create a new class to track histories. All histories are stored in this tracker. The name of the class can be anything you like. The only requirement is that it includes `Mongoid::History::Tracker`
31
-
32
- ```ruby
33
- # app/models/history_tracker.rb
34
- class HistoryTracker
35
- include Mongoid::History::Tracker
36
- end
37
- ```
38
-
39
- **Set tracker class name**
40
-
41
- Manually set the tracker class name to make sure your tracker can be found and loaded properly. You can skip this step if you manually require your tracker before using any trackables.
42
-
43
- The following example sets the tracker class name using a Rails initializer.
44
-
45
- ```ruby
46
- # config/initializers/mongoid-history.rb
47
- # initializer for mongoid-history
48
- # assuming HistoryTracker is your tracker class
49
- Mongoid::History.tracker_class_name = :history_tracker
50
- ```
51
-
52
- **Create trackable classes and objects**
53
-
54
- ```ruby
55
- class Post
56
- include Mongoid::Document
57
- include Mongoid::Timestamps
58
-
59
- # history tracking all Post documents
60
- # note: tracking will not work until #track_history is invoked
61
- include Mongoid::History::Trackable
62
-
63
- field :title
64
- field :body
65
- field :rating
66
- embeds_many :comments
67
-
68
- # telling Mongoid::History how you want to track changes
69
- track_history :on => [:title, :body], # track title and body fields only, default is :all
70
- :modifier_field => :modifier, # adds "belongs_to :modifier" to track who made the change, default is :modifier
71
- :modifier_field_inverse_of => :nil, # adds an ":inverse_of" option to the "belongs_to :modifier" relation, default is not set
72
- :version_field => :version, # adds "field :version, :type => Integer" to track current version, default is :version
73
- :track_create => false, # track document creation, default is false
74
- :track_update => true, # track document updates, default is true
75
- :track_destroy => false # track document destruction, default is false
76
- end
77
-
78
- class Comment
79
- include Mongoid::Document
80
- include Mongoid::Timestamps
81
-
82
- # declare that we want to track comments
83
- include Mongoid::History::Trackable
84
-
85
- field :title
86
- field :body
87
- embedded_in :post, :inverse_of => :comments
88
-
89
- # track title and body for all comments, scope it to post (the parent)
90
- # also track creation and destruction
91
- track_history :on => [:title, :body], :scope => :post, :track_create => true, :track_destroy => true
92
- end
93
-
94
- # the modifier class
95
- class User
96
- include Mongoid::Document
97
- include Mongoid::Timestamps
98
-
99
- field :name
100
- end
101
-
102
- user = User.create(:name => "Aaron")
103
- post = Post.create(:title => "Test", :body => "Post", :modifier => user)
104
- comment = post.comments.create(:title => "test", :body => "comment", :modifier => user)
105
- comment.history_tracks.count # should be 1
106
-
107
- comment.update_attributes(:title => "Test 2")
108
- comment.history_tracks.count # should be 2
109
-
110
- track = comment.history_tracks.last
111
-
112
- track.undo! user # comment title should be "Test"
113
-
114
- track.redo! user # comment title should be "Test 2"
115
-
116
- # undo last change
117
- comment.undo! user
118
-
119
- # undo versions 1 - 4
120
- comment.undo! user, :from => 4, :to => 1
121
-
122
- # undo last 3 versions
123
- comment.undo! user, :last => 3
124
-
125
- # redo versions 1 - 4
126
- comment.redo! user, :from => 1, :to => 4
127
-
128
- # redo last 3 versions
129
- comment.redo! user, :last => 3
130
-
131
- # redo version 1
132
- comment.redo! user, 1
133
-
134
- # delete post
135
- post.destroy
136
-
137
- # undelete post
138
- post.undo! user
139
-
140
- # disable tracking for comments within a block
141
- Comment.disable_tracking do
142
- comment.update_attributes(:title => "Test 3")
143
- end
144
-
145
- # globally disable all history tracking
146
- Mongoid::History.disable do
147
- comment.update_attributes(:title => "Test 3")
148
- user.update_attributes(:name => "Eddie Van Halen")
149
- end
150
- ```
151
-
152
- **Retrieving the list of tracked fields**
153
-
154
- ```ruby
155
- class Book
156
- ...
157
- field :title
158
- field :author
159
- field :price
160
- track_history :on => [:title, :price]
161
- end
162
-
163
- Book.tracked_fields #=> ["title", "price"]
164
- Book.tracked_field?(:title) #=> true
165
- Book.tracked_field?(:author) #=> false
166
- ```
167
-
168
- **Displaying history trackers as an audit trail**
169
-
170
- In your Controller:
171
-
172
- ```ruby
173
- # Fetch history trackers
174
- @trackers = HistoryTracker.limit(25)
175
-
176
- # get change set for the first tracker
177
- @changes = @trackers.first.tracked_changes
178
- #=> {field: {to: val1, from: val2}}
179
-
180
- # get edit set for the first tracker
181
- @edits = @trackers.first.tracked_edits
182
- #=> { add: {field: val},
183
- # remove: {field: val},
184
- # modify: { to: val1, from: val2 },
185
- # array: { add: [val2], remove: [val1] } }
186
- ```
187
-
188
- In your View, you might do something like (example in HAML format):
189
-
190
- ```haml
191
- %ul.changes
192
- - (@edits[:add]||[]).each do |k,v|
193
- %li.remove Added field #{k} value #{v}
194
-
195
- - (@edits[:modify]||[]).each do |k,v|
196
- %li.modify Changed field #{k} from #{v[:from]} to #{v[:to]}
197
-
198
- - (@edits[:array]||[]).each do |k,v|
199
- %li.modify
200
- - if v[:remove].nil?
201
- Changed field #{k} by adding #{v[:add]}
202
- - elsif v[:add].nil?
203
- Changed field #{k} by removing #{v[:remove]}
204
- - else
205
- Changed field #{k} by adding #{v[:add]} and removing #{v[:remove]}
206
-
207
- - (@edits[:remove]||[]).each do |k,v|
208
- %li.remove Removed field #{k} (was previously #{v})
209
- ```
210
-
211
- **Adding Userstamp on History Trackers**
212
-
213
- To track the User in the application who created the HistoryTracker, please add the
214
- [Mongoid::Userstamp gem](https://github.com/tbpro/mongoid_userstamp) to your HistoryTracker class.
215
- This will add a field called `created_by` and an accessor `creator` to the model (you can rename these via gem config).
216
-
217
- ```
218
- class MyHistoryTracker
219
- include Mongoid::History::Tracker
220
- include Mongoid::Userstamp
221
- end
222
- ```
223
-
224
- *Migrating Userstamp from Previous Versions*
225
-
226
- Since October 2013, Mongoid::History itself no longer supports the userstamp natively. In order to migrate, follow the
227
- instructions above then run the following command:
228
-
229
- ```
230
- MyHistoryTracker.all.each{|ht| ht.rename(:modifier_id, :created_by)
231
- ```
232
-
233
- **Using an alternate changes method**
234
-
235
- Sometimes you may wish to provide an alternate method for determining which changes should be tracked. For example, if you are using embedded documents
236
- and nested attributes, you may wish to write your own changes method that includes changes from the embedded documents.
237
-
238
- Mongoid::History provides an option named `:changes_method` which allows you to do this. It defaults to `:changes`, which is the standard changes method.
239
-
240
- Example:
241
-
242
- ```ruby
243
- class Foo
244
- include Mongoid::Document
245
- include Mongoid::Timestamps
246
- include Mongoid::History::Trackable
247
-
248
- field :bar
249
- embeds_one :baz
250
- accepts_nested_attributes_for :baz
251
-
252
- # use changes_with_baz to include baz's changes in this document's
253
- # history.
254
- track_history :changes_method => :changes_with_baz
255
-
256
- def changes_with_baz
257
- if baz.changed?
258
- changes.merge( :baz => summarized_changes(baz) )
259
- else
260
- changes
261
- end
262
- end
263
-
264
- private
265
- # This method takes the changes from an embedded doc and formats them
266
- # in a summarized way, similar to how the embedded doc appears in the
267
- # parent document's attributes
268
- def summarized_changes obj
269
- obj.changes.keys.map do |field|
270
- next unless obj.respond_to?("#{field}_change")
271
- [ { field => obj.send("#{field}_change")[0] },
272
- { field => obj.send("#{field}_change")[1] } ]
273
- end.compact.transpose.map do |fields|
274
- fields.inject({}) {|map,f| map.merge(f)}
275
- end
276
- end
277
- end
278
-
279
- class Baz
280
- include Mongoid::Document
281
- include Mongoid::Timestamps
282
-
283
- embedded_in :foo
284
- field :value
285
- end
286
- ```
287
-
288
- For more examples, check out [spec/integration/integration_spec.rb](https://github.com/aq1018/mongoid-history/blob/master/spec/integration/integration_spec.rb).
289
-
290
- Contributing to mongoid-history
291
- -------------------------------
292
-
293
- * Check out the latest code to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
294
- * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
295
- * Fork the project.
296
- * Create a feature/bugfix branch.
297
- * Commit and push until you are happy with your changes.
298
- * Make sure to add tests.
299
- * Update the CHANGELOG for the next release.
300
- * Try not to mess with the Rakefile or version.
301
- * Make a pull request.
302
-
303
- Copyright
304
- ---------
305
-
306
- Copyright (c) 2011-2012 Aaron Qian. MIT License.
307
-
308
- See [LICENSE.txt](https://github.com/aq1018/mongoid-history/blob/master/LICENSE.txt) for further details.
309
-
1
+ mongoid-history
2
+ ===============
3
+
4
+ [![Gem Version](https://badge.fury.io/rb/mongoid-history.png)](http://badge.fury.io/rb/mongoid-history)
5
+ [![Build Status](https://secure.travis-ci.org/aq1018/mongoid-history.png?branch=master)](http://travis-ci.org/aq1018/mongoid-history)
6
+ [![Dependency Status](https://gemnasium.com/aq1018/mongoid-history.png)](https://gemnasium.com/aq1018/mongoid-history)
7
+ [![Code Climate](https://codeclimate.com/github/aq1018/mongoid-history.png)](https://codeclimate.com/github/aq1018/mongoid-history)
8
+ [![Coverage Status](https://coveralls.io/repos/aq1018/mongoid-history/badge.png?branch=coveralls)](https://coveralls.io/r/aq1018/mongoid-history?branch=coveralls)
9
+
10
+ Mongoid-history tracks historical changes for any document, including embedded ones. It achieves this by storing all history tracks in a single collection that you define. 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.
11
+
12
+ This gem also 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 is probably not suitable for use cases such as a wiki (but we won't stop you either).
13
+
14
+ Stable Release
15
+ --------------
16
+
17
+ You're reading the documentation the 0.4.x release that supports Mongoid 3.x and 4.x. For 2.x compatible mongoid-history, please use a 0.2.x version from the [2.x-stable branch](https://github.com/aq1018/mongoid-history/tree/2.4-stable).
18
+
19
+ Install
20
+ -------
21
+
22
+ This gem supports Mongoid 3.x and 4.x on Ruby 1.9.3 or newer. Add it to your `Gemfile` or run `gem install mongoid-history`.
23
+
24
+ ```ruby
25
+ gem 'mongoid-history'
26
+ ```
27
+
28
+ Usage
29
+ -----
30
+
31
+ **Create a history tracker**
32
+
33
+ Create a new class to track histories. All histories are stored in this tracker. The name of the class can be anything you like. The only requirement is that it includes `Mongoid::History::Tracker`
34
+
35
+ ```ruby
36
+ # app/models/history_tracker.rb
37
+ class HistoryTracker
38
+ include Mongoid::History::Tracker
39
+ end
40
+ ```
41
+
42
+ **Set tracker class name**
43
+
44
+ Manually set the tracker class name to make sure your tracker can be found and loaded properly. You can skip this step if you manually require your tracker before using any trackables.
45
+
46
+ The following example sets the tracker class name using a Rails initializer.
47
+
48
+ ```ruby
49
+ # config/initializers/mongoid-history.rb
50
+ # initializer for mongoid-history
51
+ # assuming HistoryTracker is your tracker class
52
+ Mongoid::History.tracker_class_name = :history_tracker
53
+ ```
54
+
55
+ **Create trackable classes and objects**
56
+
57
+ ```ruby
58
+ class Post
59
+ include Mongoid::Document
60
+ include Mongoid::Timestamps
61
+
62
+ # history tracking all Post documents
63
+ # note: tracking will not work until #track_history is invoked
64
+ include Mongoid::History::Trackable
65
+
66
+ field :title
67
+ field :body
68
+ field :rating
69
+ embeds_many :comments
70
+
71
+ # telling Mongoid::History how you want to track changes
72
+ track_history :on => [:title, :body], # track title and body fields only, default is :all
73
+ :modifier_field => :modifier, # adds "belongs_to :modifier" to track who made the change, default is :modifier
74
+ :modifier_field_inverse_of => :nil, # adds an ":inverse_of" option to the "belongs_to :modifier" relation, default is not set
75
+ :version_field => :version, # adds "field :version, :type => Integer" to track current version, default is :version
76
+ :track_create => false, # track document creation, default is false
77
+ :track_update => true, # track document updates, default is true
78
+ :track_destroy => false # track document destruction, default is false
79
+ end
80
+
81
+ class Comment
82
+ include Mongoid::Document
83
+ include Mongoid::Timestamps
84
+
85
+ # declare that we want to track comments
86
+ include Mongoid::History::Trackable
87
+
88
+ field :title
89
+ field :body
90
+ embedded_in :post, :inverse_of => :comments
91
+
92
+ # track title and body for all comments, scope it to post (the parent)
93
+ # also track creation and destruction
94
+ track_history :on => [:title, :body], :scope => :post, :track_create => true, :track_destroy => true
95
+
96
+ # For embedded polymorphic relations, specify an array of model names or its polymorphic name
97
+ # e.g. :scope => [:post, :image, :video]
98
+ # :scope => :commentable
99
+
100
+ end
101
+
102
+ # the modifier class
103
+ class User
104
+ include Mongoid::Document
105
+ include Mongoid::Timestamps
106
+
107
+ field :name
108
+ end
109
+
110
+ user = User.create(:name => "Aaron")
111
+ post = Post.create(:title => "Test", :body => "Post", :modifier => user)
112
+ comment = post.comments.create(:title => "test", :body => "comment", :modifier => user)
113
+ comment.history_tracks.count # should be 1
114
+
115
+ comment.update_attributes(:title => "Test 2")
116
+ comment.history_tracks.count # should be 2
117
+
118
+ track = comment.history_tracks.last
119
+
120
+ track.undo! user # comment title should be "Test"
121
+
122
+ track.redo! user # comment title should be "Test 2"
123
+
124
+ # undo last change
125
+ comment.undo! user
126
+
127
+ # undo versions 1 - 4
128
+ comment.undo! user, :from => 4, :to => 1
129
+
130
+ # undo last 3 versions
131
+ comment.undo! user, :last => 3
132
+
133
+ # redo versions 1 - 4
134
+ comment.redo! user, :from => 1, :to => 4
135
+
136
+ # redo last 3 versions
137
+ comment.redo! user, :last => 3
138
+
139
+ # redo version 1
140
+ comment.redo! user, 1
141
+
142
+ # delete post
143
+ post.destroy
144
+
145
+ # undelete post
146
+ post.undo! user
147
+
148
+ # disable tracking for comments within a block
149
+ Comment.disable_tracking do
150
+ comment.update_attributes(:title => "Test 3")
151
+ end
152
+
153
+ # globally disable all history tracking
154
+ Mongoid::History.disable do
155
+ comment.update_attributes(:title => "Test 3")
156
+ user.update_attributes(:name => "Eddie Van Halen")
157
+ end
158
+ ```
159
+
160
+ **Retrieving the list of tracked fields**
161
+
162
+ ```ruby
163
+ class Book
164
+ ...
165
+ field :title
166
+ field :author
167
+ field :price
168
+ track_history :on => [:title, :price]
169
+ end
170
+
171
+ Book.tracked_fields #=> ["title", "price"]
172
+ Book.tracked_field?(:title) #=> true
173
+ Book.tracked_field?(:author) #=> false
174
+ ```
175
+
176
+ **Displaying history trackers as an audit trail**
177
+
178
+ In your Controller:
179
+
180
+ ```ruby
181
+ # Fetch history trackers
182
+ @trackers = HistoryTracker.limit(25)
183
+
184
+ # get change set for the first tracker
185
+ @changes = @trackers.first.tracked_changes
186
+ #=> {field: {to: val1, from: val2}}
187
+
188
+ # get edit set for the first tracker
189
+ @edits = @trackers.first.tracked_edits
190
+ #=> { add: {field: val},
191
+ # remove: {field: val},
192
+ # modify: { to: val1, from: val2 },
193
+ # array: { add: [val2], remove: [val1] } }
194
+ ```
195
+
196
+ In your View, you might do something like (example in HAML format):
197
+
198
+ ```haml
199
+ %ul.changes
200
+ - (@edits[:add]||[]).each do |k,v|
201
+ %li.remove Added field #{k} value #{v}
202
+
203
+ - (@edits[:modify]||[]).each do |k,v|
204
+ %li.modify Changed field #{k} from #{v[:from]} to #{v[:to]}
205
+
206
+ - (@edits[:array]||[]).each do |k,v|
207
+ %li.modify
208
+ - if v[:remove].nil?
209
+ Changed field #{k} by adding #{v[:add]}
210
+ - elsif v[:add].nil?
211
+ Changed field #{k} by removing #{v[:remove]}
212
+ - else
213
+ Changed field #{k} by adding #{v[:add]} and removing #{v[:remove]}
214
+
215
+ - (@edits[:remove]||[]).each do |k,v|
216
+ %li.remove Removed field #{k} (was previously #{v})
217
+ ```
218
+
219
+ **Adding Userstamp on History Trackers**
220
+
221
+ To track the User in the application who created the HistoryTracker, please add the
222
+ [Mongoid::Userstamp gem](https://github.com/tbpro/mongoid_userstamp) to your HistoryTracker class.
223
+ This will add a field called `created_by` and an accessor `creator` to the model (you can rename these via gem config).
224
+
225
+ ```
226
+ class MyHistoryTracker
227
+ include Mongoid::History::Tracker
228
+ include Mongoid::Userstamp
229
+ end
230
+ ```
231
+
232
+ *Migrating Userstamp from Previous Versions*
233
+
234
+ Since October 2013 (mongoid-history version 0.4.1 and onwards), Mongoid::History itself no longer supports the userstamp natively. In order to migrate, follow the
235
+ instructions above then run the following command:
236
+
237
+ ```
238
+ MyHistoryTracker.all.each{|ht| ht.rename(:modifier_id, :created_by)
239
+ ```
240
+
241
+ **Using an alternate changes method**
242
+
243
+ Sometimes you may wish to provide an alternate method for determining which changes should be tracked. For example, if you are using embedded documents
244
+ and nested attributes, you may wish to write your own changes method that includes changes from the embedded documents.
245
+
246
+ Mongoid::History provides an option named `:changes_method` which allows you to do this. It defaults to `:changes`, which is the standard changes method.
247
+
248
+ Example:
249
+
250
+ ```ruby
251
+ class Foo
252
+ include Mongoid::Document
253
+ include Mongoid::Timestamps
254
+ include Mongoid::History::Trackable
255
+
256
+ field :bar
257
+ embeds_one :baz
258
+ accepts_nested_attributes_for :baz
259
+
260
+ # use changes_with_baz to include baz's changes in this document's
261
+ # history.
262
+ track_history :changes_method => :changes_with_baz
263
+
264
+ def changes_with_baz
265
+ if baz.changed?
266
+ changes.merge( :baz => summarized_changes(baz) )
267
+ else
268
+ changes
269
+ end
270
+ end
271
+
272
+ private
273
+ # This method takes the changes from an embedded doc and formats them
274
+ # in a summarized way, similar to how the embedded doc appears in the
275
+ # parent document's attributes
276
+ def summarized_changes obj
277
+ obj.changes.keys.map do |field|
278
+ next unless obj.respond_to?("#{field}_change")
279
+ [ { field => obj.send("#{field}_change")[0] },
280
+ { field => obj.send("#{field}_change")[1] } ]
281
+ end.compact.transpose.map do |fields|
282
+ fields.inject({}) {|map,f| map.merge(f)}
283
+ end
284
+ end
285
+ end
286
+
287
+ class Baz
288
+ include Mongoid::Document
289
+ include Mongoid::Timestamps
290
+
291
+ embedded_in :foo
292
+ field :value
293
+ end
294
+ ```
295
+
296
+ For more examples, check out [spec/integration/integration_spec.rb](https://github.com/aq1018/mongoid-history/blob/master/spec/integration/integration_spec.rb).
297
+
298
+ Contributing to mongoid-history
299
+ -------------------------------
300
+
301
+ You're encouraged to contribute to this library. See [CONTRIBUTING](CONTRIBUTING.md) for details.
302
+
303
+ Copyright
304
+ ---------
305
+
306
+ Copyright (c) 2011-2012 Aaron Qian. MIT License.
307
+
308
+ See [LICENSE.txt](https://github.com/aq1018/mongoid-history/blob/master/LICENSE.txt) for further details.
309
+
310
+
311
+
312
+ [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/aq1018/mongoid-history/trend.png)](https://bitdeli.com/free "Bitdeli Badge")