mongoid-history 0.6.1 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +49 -40
- data/CHANGELOG.md +14 -0
- data/Gemfile +7 -5
- data/README.md +70 -6
- data/RELEASING.md +67 -0
- data/Rakefile +1 -1
- data/UPGRADING.md +34 -0
- data/lib/mongoid/history/attributes/create.rb +2 -2
- data/lib/mongoid/history/attributes/destroy.rb +9 -9
- data/lib/mongoid/history/attributes/update.rb +11 -9
- data/lib/mongoid/history/options.rb +15 -20
- data/lib/mongoid/history/trackable.rb +47 -27
- data/lib/mongoid/history/tracker.rb +15 -9
- data/lib/mongoid/history/version.rb +1 -1
- data/lib/mongoid/history.rb +1 -1
- data/mongoid-history.gemspec +1 -1
- data/spec/integration/embedded_in_polymorphic_spec.rb +1 -1
- data/spec/integration/integration_spec.rb +37 -31
- data/spec/integration/multi_relation_spec.rb +1 -1
- data/spec/integration/multiple_trackers_spec.rb +71 -0
- data/spec/integration/nested_embedded_polymorphic_documents_spec.rb +2 -2
- data/spec/integration/track_history_order_spec.rb +52 -0
- data/spec/integration/validation_failure_spec.rb +63 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/unit/attributes/base_spec.rb +3 -3
- data/spec/unit/attributes/destroy_spec.rb +1 -1
- data/spec/unit/attributes/update_spec.rb +113 -2
- data/spec/unit/callback_options_spec.rb +159 -0
- data/spec/unit/my_instance_methods_spec.rb +1 -1
- data/spec/unit/options_spec.rb +62 -61
- data/spec/unit/singleton_methods_spec.rb +13 -13
- data/spec/unit/trackable_spec.rb +114 -11
- metadata +15 -5
@@ -7,14 +7,16 @@ module Mongoid
|
|
7
7
|
def track_history(options = {})
|
8
8
|
extend EmbeddedMethods
|
9
9
|
|
10
|
-
|
11
|
-
options = options_parser.parse(options)
|
10
|
+
history_options = Mongoid::History::Options.new(self, options)
|
12
11
|
|
13
|
-
field options[:version_field].to_sym, type: Integer
|
12
|
+
field history_options.options[:version_field].to_sym, type: Integer
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
unless history_options.options[:modifier_field].nil?
|
15
|
+
belongs_to_modifier_options = { class_name: Mongoid::History.modifier_class_name }
|
16
|
+
belongs_to_modifier_options[:inverse_of] = history_options.options[:modifier_field_inverse_of] if history_options.options.key?(:modifier_field_inverse_of)
|
17
|
+
belongs_to_modifier_options[:optional] = true if history_options.options[:modifier_field_optional] && Mongoid::Compatibility::Version.mongoid6_or_newer?
|
18
|
+
belongs_to history_options.options[:modifier_field].to_sym, belongs_to_modifier_options
|
19
|
+
end
|
18
20
|
|
19
21
|
include MyInstanceMethods
|
20
22
|
extend SingletonMethods
|
@@ -22,12 +24,13 @@ module Mongoid
|
|
22
24
|
delegate :history_trackable_options, to: 'self.class'
|
23
25
|
delegate :track_history?, to: 'self.class'
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
-
|
27
|
+
callback_options = history_options.options.slice(:if, :unless)
|
28
|
+
around_update :track_update, callback_options if history_options.options[:track_update]
|
29
|
+
around_create :track_create, callback_options if history_options.options[:track_create]
|
30
|
+
around_destroy :track_destroy, callback_options if history_options.options[:track_destroy]
|
28
31
|
|
29
32
|
Mongoid::History.trackable_class_options ||= {}
|
30
|
-
Mongoid::History.trackable_class_options[
|
33
|
+
Mongoid::History.trackable_class_options[history_options.scope] = history_options
|
31
34
|
end
|
32
35
|
|
33
36
|
def history_settings(options = {})
|
@@ -131,7 +134,7 @@ module Mongoid
|
|
131
134
|
elsif options[:last]
|
132
135
|
versions = history_tracks.limit(options[:last])
|
133
136
|
else
|
134
|
-
|
137
|
+
raise 'Invalid options, please specify (:from / :to) keys or :last key.'
|
135
138
|
end
|
136
139
|
else
|
137
140
|
options_or_version = options_or_version.to_a if options_or_version.is_a?(Range)
|
@@ -178,7 +181,7 @@ module Mongoid
|
|
178
181
|
relation.class_name == node.metadata.class_name.to_s && relation.name == node.metadata.name
|
179
182
|
else
|
180
183
|
relation.class_name == node.relation_metadata.class_name.to_s &&
|
181
|
-
|
184
|
+
relation.name == node.relation_metadata.name
|
182
185
|
end
|
183
186
|
end
|
184
187
|
end
|
@@ -219,11 +222,12 @@ module Mongoid
|
|
219
222
|
def history_tracker_attributes(action)
|
220
223
|
return @history_tracker_attributes if @history_tracker_attributes
|
221
224
|
|
225
|
+
modifier_field = history_trackable_options[:modifier_field]
|
222
226
|
@history_tracker_attributes = {
|
223
227
|
association_chain: traverse_association_chain,
|
224
|
-
scope: related_scope
|
225
|
-
modifier: send(history_trackable_options[:modifier_field])
|
228
|
+
scope: related_scope
|
226
229
|
}
|
230
|
+
@history_tracker_attributes[:modifier] = send(modifier_field) if modifier_field
|
227
231
|
|
228
232
|
original, modified = transform_changes(modified_attributes_for_action(action))
|
229
233
|
|
@@ -232,16 +236,16 @@ module Mongoid
|
|
232
236
|
@history_tracker_attributes
|
233
237
|
end
|
234
238
|
|
235
|
-
def track_create
|
236
|
-
track_history_for_action(:create)
|
239
|
+
def track_create(&block)
|
240
|
+
track_history_for_action(:create, &block)
|
237
241
|
end
|
238
242
|
|
239
|
-
def track_update
|
240
|
-
track_history_for_action(:update)
|
243
|
+
def track_update(&block)
|
244
|
+
track_history_for_action(:update, &block)
|
241
245
|
end
|
242
246
|
|
243
|
-
def track_destroy
|
244
|
-
track_history_for_action(:destroy) unless destroyed?
|
247
|
+
def track_destroy(&block)
|
248
|
+
track_history_for_action(:destroy, &block) unless destroyed?
|
245
249
|
end
|
246
250
|
|
247
251
|
def clear_trackable_memoization
|
@@ -273,9 +277,20 @@ module Mongoid
|
|
273
277
|
if track_history_for_action?(action)
|
274
278
|
current_version = (send(history_trackable_options[:version_field]) || 0) + 1
|
275
279
|
send("#{history_trackable_options[:version_field]}=", current_version)
|
276
|
-
self.class.tracker_class.create!(history_tracker_attributes(action.to_sym).merge(version: current_version, action: action.to_s, trackable: self))
|
280
|
+
last_track = self.class.tracker_class.create!(history_tracker_attributes(action.to_sym).merge(version: current_version, action: action.to_s, trackable: self))
|
277
281
|
end
|
282
|
+
|
278
283
|
clear_trackable_memoization
|
284
|
+
|
285
|
+
begin
|
286
|
+
yield
|
287
|
+
rescue => e
|
288
|
+
if track_history_for_action?(action)
|
289
|
+
send("#{history_trackable_options[:version_field]}=", current_version - 1)
|
290
|
+
last_track.destroy
|
291
|
+
end
|
292
|
+
raise e
|
293
|
+
end
|
279
294
|
end
|
280
295
|
end
|
281
296
|
|
@@ -414,7 +429,12 @@ module Mongoid
|
|
414
429
|
#
|
415
430
|
# @return [ Array < String > ] the list of reserved database field names
|
416
431
|
def reserved_tracked_fields
|
417
|
-
@reserved_tracked_fields ||=
|
432
|
+
@reserved_tracked_fields ||= begin
|
433
|
+
fields = ['_id', history_trackable_options[:version_field].to_s]
|
434
|
+
modifier_field = history_trackable_options[:modifier_field]
|
435
|
+
fields << "#{modifier_field}_id" if modifier_field
|
436
|
+
fields
|
437
|
+
end
|
418
438
|
end
|
419
439
|
|
420
440
|
def field_formats
|
@@ -445,8 +465,8 @@ module Mongoid
|
|
445
465
|
def tracked_embeds_one
|
446
466
|
@tracked_embeds_one ||= begin
|
447
467
|
reflect_on_all_associations(:embeds_one)
|
448
|
-
|
449
|
-
|
468
|
+
.map(&:key)
|
469
|
+
.select { |rel| history_trackable_options[:relations][:embeds_one].include? rel }
|
450
470
|
end
|
451
471
|
end
|
452
472
|
|
@@ -469,8 +489,8 @@ module Mongoid
|
|
469
489
|
def tracked_embeds_many
|
470
490
|
@tracked_embeds_many ||= begin
|
471
491
|
reflect_on_all_associations(:embeds_many)
|
472
|
-
|
473
|
-
|
492
|
+
.map(&:key)
|
493
|
+
.select { |rel| history_trackable_options[:relations][:embeds_many].include? rel }
|
474
494
|
end
|
475
495
|
end
|
476
496
|
|
@@ -483,7 +503,7 @@ module Mongoid
|
|
483
503
|
end
|
484
504
|
|
485
505
|
def history_trackable_options
|
486
|
-
@history_trackable_options ||= Mongoid::History.trackable_class_options[trackable_scope]
|
506
|
+
@history_trackable_options ||= Mongoid::History.trackable_class_options[trackable_scope].prepared
|
487
507
|
end
|
488
508
|
|
489
509
|
def clear_trackable_memoization
|
@@ -14,12 +14,16 @@ module Mongoid
|
|
14
14
|
field :version, type: Integer
|
15
15
|
field :action, type: String
|
16
16
|
field :scope, type: String
|
17
|
-
|
17
|
+
modifier_options = {
|
18
|
+
class_name: Mongoid::History.modifier_class_name
|
19
|
+
}
|
20
|
+
modifier_options[:optional] = true if Mongoid::Compatibility::Version.mongoid6_or_newer?
|
21
|
+
belongs_to :modifier, modifier_options
|
18
22
|
|
19
23
|
index(scope: 1)
|
20
24
|
index(association_chain: 1)
|
21
25
|
|
22
|
-
Mongoid::History.tracker_class_name
|
26
|
+
Mongoid::History.tracker_class_name ||= name.tableize.singularize.to_sym
|
23
27
|
end
|
24
28
|
|
25
29
|
def undo!(modifier = nil)
|
@@ -50,7 +54,7 @@ module Mongoid
|
|
50
54
|
undo_hash = affected.easy_unmerge(modified)
|
51
55
|
undo_hash.easy_merge!(original)
|
52
56
|
modifier_field = trackable.history_trackable_options[:modifier_field]
|
53
|
-
undo_hash[modifier_field] = modifier
|
57
|
+
undo_hash[modifier_field] = modifier if modifier_field
|
54
58
|
(modified.keys - undo_hash.keys).each do |k|
|
55
59
|
undo_hash[k] = nil
|
56
60
|
end
|
@@ -61,7 +65,7 @@ module Mongoid
|
|
61
65
|
redo_hash = affected.easy_unmerge(original)
|
62
66
|
redo_hash.easy_merge!(modified)
|
63
67
|
modifier_field = trackable.history_trackable_options[:modifier_field]
|
64
|
-
redo_hash[modifier_field] = modifier
|
68
|
+
redo_hash[modifier_field] = modifier if modifier_field
|
65
69
|
localize_keys(redo_hash)
|
66
70
|
end
|
67
71
|
|
@@ -180,7 +184,7 @@ module Mongoid
|
|
180
184
|
elsif trackable_parent.class.embeds_many?(name)
|
181
185
|
trackable_parent.get_embedded(name).create!(localize_keys(original))
|
182
186
|
else
|
183
|
-
|
187
|
+
raise 'This should never happen. Please report bug!'
|
184
188
|
end
|
185
189
|
end
|
186
190
|
|
@@ -205,7 +209,7 @@ module Mongoid
|
|
205
209
|
elsif doc.class.embeds_many?(name)
|
206
210
|
doc.get_embedded(name).unscoped.where(_id: node['id']).first
|
207
211
|
else
|
208
|
-
|
212
|
+
raise 'This should never happen. Please report bug.'
|
209
213
|
end
|
210
214
|
documents << doc
|
211
215
|
break if chain.empty?
|
@@ -215,9 +219,11 @@ module Mongoid
|
|
215
219
|
|
216
220
|
def localize_keys(hash)
|
217
221
|
klass = association_chain.first['name'].constantize
|
218
|
-
klass.localized_fields
|
219
|
-
|
220
|
-
|
222
|
+
if klass.respond_to?(:localized_fields)
|
223
|
+
klass.localized_fields.keys.each do |name|
|
224
|
+
hash["#{name}_translations"] = hash.delete(name) if hash[name].present?
|
225
|
+
end
|
226
|
+
end
|
221
227
|
hash
|
222
228
|
end
|
223
229
|
|
data/lib/mongoid/history.rb
CHANGED
@@ -11,7 +11,7 @@ require 'mongoid/history/trackable'
|
|
11
11
|
|
12
12
|
module Mongoid
|
13
13
|
module History
|
14
|
-
GLOBAL_TRACK_HISTORY_FLAG = 'mongoid_history_trackable_enabled'
|
14
|
+
GLOBAL_TRACK_HISTORY_FLAG = 'mongoid_history_trackable_enabled'.freeze
|
15
15
|
|
16
16
|
class << self
|
17
17
|
attr_accessor :tracker_class_name
|
data/mongoid-history.gemspec
CHANGED
@@ -20,6 +20,6 @@ Gem::Specification.new do |s|
|
|
20
20
|
|
21
21
|
s.add_runtime_dependency 'easy_diff'
|
22
22
|
s.add_runtime_dependency 'mongoid', '>= 3.0'
|
23
|
-
s.add_runtime_dependency 'mongoid-compatibility'
|
23
|
+
s.add_runtime_dependency 'mongoid-compatibility', '>= 0.5.1'
|
24
24
|
s.add_runtime_dependency 'activesupport'
|
25
25
|
end
|
@@ -68,7 +68,7 @@ describe Mongoid::History::Tracker do
|
|
68
68
|
track_create: true, # track document creation, default is false
|
69
69
|
track_update: true, # track document updates, default is true
|
70
70
|
track_destroy: false, # track document destruction, default is false
|
71
|
-
scope: [
|
71
|
+
scope: %i[real_state company]
|
72
72
|
end
|
73
73
|
|
74
74
|
class User
|
@@ -18,7 +18,7 @@ describe Mongoid::History do
|
|
18
18
|
|
19
19
|
accepts_nested_attributes_for :tags, allow_destroy: true
|
20
20
|
|
21
|
-
track_history on: [
|
21
|
+
track_history on: %i[title body], track_destroy: true
|
22
22
|
end
|
23
23
|
|
24
24
|
class Comment
|
@@ -29,7 +29,7 @@ describe Mongoid::History do
|
|
29
29
|
field :t, as: :title
|
30
30
|
field :body
|
31
31
|
embedded_in :commentable, polymorphic: true
|
32
|
-
track_history on: [
|
32
|
+
track_history on: %i[title body], scope: :post, track_create: true, track_destroy: true
|
33
33
|
end
|
34
34
|
|
35
35
|
class Section
|
@@ -54,7 +54,7 @@ describe Mongoid::History do
|
|
54
54
|
field :city
|
55
55
|
field :country
|
56
56
|
field :aliases, type: Array
|
57
|
-
track_history except: [
|
57
|
+
track_history except: %i[email updated_at]
|
58
58
|
end
|
59
59
|
|
60
60
|
class Tag
|
@@ -122,6 +122,7 @@ describe Mongoid::History do
|
|
122
122
|
|
123
123
|
describe 'on destruction' do
|
124
124
|
it 'should have two history track records in post' do
|
125
|
+
post # This will create history track records for creation
|
125
126
|
expect do
|
126
127
|
post.destroy
|
127
128
|
end.to change(Tracker, :count).by(1)
|
@@ -147,12 +148,14 @@ describe Mongoid::History do
|
|
147
148
|
|
148
149
|
describe 'on update non-embedded' do
|
149
150
|
it 'should create a history track if changed attributes match tracked attributes' do
|
151
|
+
post # This will create history track records for creation
|
150
152
|
expect do
|
151
153
|
post.update_attributes(title: 'Another Test')
|
152
154
|
end.to change(Tracker, :count).by(1)
|
153
155
|
end
|
154
156
|
|
155
157
|
it 'should not create a history track if changed attributes do not match tracked attributes' do
|
158
|
+
post # This will create history track records for creation
|
156
159
|
expect do
|
157
160
|
post.update_attributes(rating: 'untracked')
|
158
161
|
end.to change(Tracker, :count).by(0)
|
@@ -188,8 +191,9 @@ describe Mongoid::History do
|
|
188
191
|
end
|
189
192
|
|
190
193
|
it 'should assign version on post' do
|
194
|
+
expect(post.version).to eq(1) # Created
|
191
195
|
post.update_attributes(title: 'Another Test')
|
192
|
-
expect(post.version).to eq(
|
196
|
+
expect(post.version).to eq(2) # Updated
|
193
197
|
end
|
194
198
|
|
195
199
|
it 'should assign scope' do
|
@@ -205,16 +209,16 @@ describe Mongoid::History do
|
|
205
209
|
it 'should exclude defined options' do
|
206
210
|
name = user.name
|
207
211
|
user.update_attributes(name: 'Aaron2', email: 'aaronsnewemail@randomemail.com')
|
208
|
-
expect(user.history_tracks.
|
209
|
-
expect(user.history_tracks.
|
210
|
-
expect(user.history_tracks.
|
211
|
-
expect(user.history_tracks.
|
212
|
+
expect(user.history_tracks.last.original.keys).to eq(['n'])
|
213
|
+
expect(user.history_tracks.last.original['n']).to eq(name)
|
214
|
+
expect(user.history_tracks.last.modified.keys).to eq(['n'])
|
215
|
+
expect(user.history_tracks.last.modified['n']).to eq(user.name)
|
212
216
|
end
|
213
217
|
|
214
218
|
it 'should undo field changes' do
|
215
219
|
name = user.name
|
216
220
|
user.update_attributes(name: 'Aaron2', email: 'aaronsnewemail@randomemail.com')
|
217
|
-
user.history_tracks.
|
221
|
+
user.history_tracks.last.undo! nil
|
218
222
|
expect(user.reload.name).to eq(name)
|
219
223
|
end
|
220
224
|
|
@@ -223,21 +227,21 @@ describe Mongoid::History do
|
|
223
227
|
expect(post.reload.title).to be_nil
|
224
228
|
post.update_attributes(title: 'Aaron2')
|
225
229
|
expect(post.reload.title).to eq('Aaron2')
|
226
|
-
post.history_tracks.
|
230
|
+
post.history_tracks.last.undo! nil
|
227
231
|
expect(post.reload.title).to be_nil
|
228
232
|
end
|
229
233
|
|
230
234
|
it 'should track array changes' do
|
231
235
|
aliases = user.aliases
|
232
|
-
user.update_attributes(aliases: %w
|
233
|
-
expect(user.history_tracks.
|
234
|
-
expect(user.history_tracks.
|
236
|
+
user.update_attributes(aliases: %w[bob joe])
|
237
|
+
expect(user.history_tracks.last.original['aliases']).to eq(aliases)
|
238
|
+
expect(user.history_tracks.last.modified['aliases']).to eq(user.aliases)
|
235
239
|
end
|
236
240
|
|
237
241
|
it 'should undo array changes' do
|
238
242
|
aliases = user.aliases
|
239
|
-
user.update_attributes(aliases: %w
|
240
|
-
user.history_tracks.
|
243
|
+
user.update_attributes(aliases: %w[bob joe])
|
244
|
+
user.history_tracks.last.undo! nil
|
241
245
|
expect(user.reload.aliases).to eq(aliases)
|
242
246
|
end
|
243
247
|
end
|
@@ -259,7 +263,7 @@ describe Mongoid::History do
|
|
259
263
|
end
|
260
264
|
end
|
261
265
|
context 'update action' do
|
262
|
-
subject { user.history_tracks.
|
266
|
+
subject { user.history_tracks.last.tracked_changes }
|
263
267
|
before do
|
264
268
|
user.update_attributes(name: 'Aaron2', email: nil, country: '', city: nil, phone: '867-5309', aliases: ['', 'bill', 'james'])
|
265
269
|
end
|
@@ -305,7 +309,7 @@ describe Mongoid::History do
|
|
305
309
|
end
|
306
310
|
end
|
307
311
|
context 'update action' do
|
308
|
-
subject { user.history_tracks.
|
312
|
+
subject { user.history_tracks.last.tracked_edits }
|
309
313
|
before do
|
310
314
|
user.update_attributes(name: 'Aaron2', email: nil, country: '', city: nil, phone: '867-5309', aliases: ['', 'bill', 'james'])
|
311
315
|
end
|
@@ -323,12 +327,12 @@ describe Mongoid::History do
|
|
323
327
|
expect(subject[:array]).to eq({ aliases: { remove: ['bob'], add: ['', 'bill', 'james'] } }.with_indifferent_access)
|
324
328
|
end
|
325
329
|
it 'should not track unmodified field' do
|
326
|
-
%w
|
330
|
+
%w[add modify remove array].each do |edit|
|
327
331
|
expect(subject[edit][:address]).to be_nil
|
328
332
|
end
|
329
333
|
end
|
330
334
|
it 'should not track untracked fields' do
|
331
|
-
%w
|
335
|
+
%w[add modify remove array].each do |edit|
|
332
336
|
expect(subject[edit][:email]).to be_nil
|
333
337
|
end
|
334
338
|
end
|
@@ -348,12 +352,14 @@ describe Mongoid::History do
|
|
348
352
|
|
349
353
|
describe 'on update non-embedded twice' do
|
350
354
|
it 'should assign version on post' do
|
355
|
+
expect(post.version).to eq(1)
|
351
356
|
post.update_attributes(title: 'Test2')
|
352
357
|
post.update_attributes(title: 'Test3')
|
353
|
-
expect(post.version).to eq(
|
358
|
+
expect(post.version).to eq(3)
|
354
359
|
end
|
355
360
|
|
356
361
|
it 'should create a history track if changed attributes match tracked attributes' do
|
362
|
+
post # Created
|
357
363
|
expect do
|
358
364
|
post.update_attributes(title: 'Test2')
|
359
365
|
post.update_attributes(title: 'Test3')
|
@@ -369,7 +375,7 @@ describe Mongoid::History do
|
|
369
375
|
it 'should assign modified fields' do
|
370
376
|
post.update_attributes(title: 'Test2')
|
371
377
|
post.update_attributes(title: 'Test3')
|
372
|
-
expect(post.history_tracks.where(version:
|
378
|
+
expect(post.history_tracks.where(version: 3).first.modified).to eq(
|
373
379
|
'title' => 'Test3'
|
374
380
|
)
|
375
381
|
end
|
@@ -377,7 +383,7 @@ describe Mongoid::History do
|
|
377
383
|
it 'should assign original fields' do
|
378
384
|
post.update_attributes(title: 'Test2')
|
379
385
|
post.update_attributes(title: 'Test3')
|
380
|
-
expect(post.history_tracks.where(version:
|
386
|
+
expect(post.history_tracks.where(version: 3).first.original).to eq(
|
381
387
|
'title' => 'Test2'
|
382
388
|
)
|
383
389
|
end
|
@@ -504,7 +510,7 @@ describe Mongoid::History do
|
|
504
510
|
it 'should be possible to create with redo after undo create embedded from parent' do
|
505
511
|
comment # initialize
|
506
512
|
post.comments.create!(title: 'The second one')
|
507
|
-
track = post.history_tracks
|
513
|
+
track = post.history_tracks[2]
|
508
514
|
track.undo!(user)
|
509
515
|
track.redo!(user)
|
510
516
|
post.reload
|
@@ -552,14 +558,14 @@ describe Mongoid::History do
|
|
552
558
|
describe 'non-embedded' do
|
553
559
|
it 'should undo changes' do
|
554
560
|
post.update_attributes(title: 'Test2')
|
555
|
-
post.history_tracks.where(version:
|
561
|
+
post.history_tracks.where(version: 2).last.undo!(user)
|
556
562
|
post.reload
|
557
563
|
expect(post.title).to eq('Test')
|
558
564
|
end
|
559
565
|
|
560
566
|
it 'should undo destruction' do
|
561
567
|
post.destroy
|
562
|
-
post.history_tracks.where(version:
|
568
|
+
post.history_tracks.where(version: 2).last.undo!(user)
|
563
569
|
expect(Post.find(post.id).title).to eq('Test')
|
564
570
|
end
|
565
571
|
|
@@ -568,12 +574,12 @@ describe Mongoid::History do
|
|
568
574
|
post.update_attributes(title: 'Test2')
|
569
575
|
post.history_tracks.last.undo!(user)
|
570
576
|
post.reload
|
571
|
-
expect(post.history_tracks.count).to eq(
|
577
|
+
expect(post.history_tracks.count).to eq(4)
|
572
578
|
end
|
573
579
|
|
574
580
|
it 'should assign user as the modifier of the newly created history track' do
|
575
581
|
post.update_attributes(title: 'Test2')
|
576
|
-
post.history_tracks.where(version:
|
582
|
+
post.history_tracks.where(version: 2).last.undo!(user)
|
577
583
|
post.reload
|
578
584
|
expect(post.history_tracks.where(version: 2).last.modifier).to eq(user)
|
579
585
|
end
|
@@ -590,7 +596,7 @@ describe Mongoid::History do
|
|
590
596
|
|
591
597
|
it 'should be destroyed after undo and redo' do
|
592
598
|
post.destroy
|
593
|
-
track = post.history_tracks.where(version:
|
599
|
+
track = post.history_tracks.where(version: 2).last
|
594
600
|
track.undo!(user)
|
595
601
|
track.redo!(user)
|
596
602
|
expect(Post.where(_id: post.id).first).to be_nil
|
@@ -639,7 +645,7 @@ describe Mongoid::History do
|
|
639
645
|
describe 'undo' do
|
640
646
|
{ 'undo' => [nil], 'undo!' => [nil, :reload] }.each do |test_method, methods|
|
641
647
|
methods.each do |method|
|
642
|
-
context
|
648
|
+
context (method || 'instance').to_s do
|
643
649
|
it 'recognizes :from, :to options' do
|
644
650
|
comment.send test_method, user, from: 4, to: 2
|
645
651
|
comment.send(method) if method
|
@@ -694,7 +700,7 @@ describe Mongoid::History do
|
|
694
700
|
|
695
701
|
describe 'redo' do
|
696
702
|
[nil, :reload].each do |method|
|
697
|
-
context
|
703
|
+
context (method || 'instance').to_s do
|
698
704
|
before :each do
|
699
705
|
comment.update_attributes(title: 'Test5')
|
700
706
|
end
|
@@ -919,7 +925,7 @@ describe Mongoid::History do
|
|
919
925
|
track_history on: [:foo], changes_method: :my_changes
|
920
926
|
|
921
927
|
def my_changes
|
922
|
-
{ foo: %w
|
928
|
+
{ foo: %w[bar baz] }
|
923
929
|
end
|
924
930
|
end
|
925
931
|
end
|
@@ -10,7 +10,7 @@ describe Mongoid::History::Tracker do
|
|
10
10
|
belongs_to :user, inverse_of: :models
|
11
11
|
has_and_belongs_to_many :external_users, class_name: 'User', inverse_of: :external_models
|
12
12
|
|
13
|
-
track_history on: [
|
13
|
+
track_history on: %i[name user external_user_ids], # track title and body fields only, default is :all
|
14
14
|
modifier_field: :modifier, # adds "referenced_in :modifier" to track who made the change, default is :modifier
|
15
15
|
modifier_field_inverse_of: nil, # no inverse modifier relationship
|
16
16
|
version_field: :version, # adds "field :version, :type => Integer" to track current version, default is :version
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mongoid::History do
|
4
|
+
before :all do
|
5
|
+
Mongoid::History.tracker_class_name = nil
|
6
|
+
|
7
|
+
module MultipleTrackersSpec
|
8
|
+
class First
|
9
|
+
include Mongoid::Document
|
10
|
+
include Mongoid::History::Trackable
|
11
|
+
|
12
|
+
field :text, type: String
|
13
|
+
track_history on: [:text],
|
14
|
+
track_create: true,
|
15
|
+
track_update: true,
|
16
|
+
track_destroy: true,
|
17
|
+
tracker_class_name: :first_history_tracker
|
18
|
+
end
|
19
|
+
|
20
|
+
class Second
|
21
|
+
include Mongoid::Document
|
22
|
+
include Mongoid::History::Trackable
|
23
|
+
|
24
|
+
field :text, type: String
|
25
|
+
track_history on: [:text],
|
26
|
+
track_create: true,
|
27
|
+
track_update: true,
|
28
|
+
track_destroy: true,
|
29
|
+
tracker_class_name: :second_history_tracker
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class FirstHistoryTracker
|
34
|
+
include Mongoid::History::Tracker
|
35
|
+
end
|
36
|
+
|
37
|
+
class SecondHistoryTracker
|
38
|
+
include Mongoid::History::Tracker
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should be possible to have different trackers for each class' do
|
43
|
+
expect(FirstHistoryTracker.count).to eq(0)
|
44
|
+
expect(SecondHistoryTracker.count).to eq(0)
|
45
|
+
expect(MultipleTrackersSpec::First.tracker_class).to be FirstHistoryTracker
|
46
|
+
expect(MultipleTrackersSpec::Second.tracker_class).to be SecondHistoryTracker
|
47
|
+
|
48
|
+
foo = MultipleTrackersSpec::First.new
|
49
|
+
foo.save
|
50
|
+
|
51
|
+
bar = MultipleTrackersSpec::Second.new
|
52
|
+
bar.save
|
53
|
+
|
54
|
+
expect(FirstHistoryTracker.count).to eq 1
|
55
|
+
expect(SecondHistoryTracker.count).to eq 1
|
56
|
+
|
57
|
+
foo.text = "I'm foo"
|
58
|
+
foo.save
|
59
|
+
bar.text = "I'm bar"
|
60
|
+
bar.save
|
61
|
+
|
62
|
+
expect(FirstHistoryTracker.count).to eq 2
|
63
|
+
expect(SecondHistoryTracker.count).to eq 2
|
64
|
+
|
65
|
+
foo.destroy
|
66
|
+
bar.destroy
|
67
|
+
|
68
|
+
expect(FirstHistoryTracker.count).to eq 3
|
69
|
+
expect(SecondHistoryTracker.count).to eq 3
|
70
|
+
end
|
71
|
+
end
|
@@ -48,7 +48,7 @@ describe Mongoid::History::Tracker do
|
|
48
48
|
track_create: true,
|
49
49
|
track_update: true,
|
50
50
|
track_destroy: true,
|
51
|
-
scope: [
|
51
|
+
scope: %i[modelone modeltwo]
|
52
52
|
end
|
53
53
|
|
54
54
|
class EmbeddedTwo
|
@@ -64,7 +64,7 @@ describe Mongoid::History::Tracker do
|
|
64
64
|
track_create: true,
|
65
65
|
track_update: true,
|
66
66
|
track_destroy: true,
|
67
|
-
scope: [
|
67
|
+
scope: %i[modelone modeltwo]
|
68
68
|
end
|
69
69
|
|
70
70
|
class User
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mongoid::History::Tracker do
|
4
|
+
it 'should not track fields when track_history not called' do
|
5
|
+
class NotModel
|
6
|
+
include Mongoid::Document
|
7
|
+
include Mongoid::History::Trackable
|
8
|
+
|
9
|
+
field :foo
|
10
|
+
end
|
11
|
+
|
12
|
+
expect(NotModel.respond_to?(:tracked?)).to be false
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should track fields when track_history called inside class and before fields' do
|
16
|
+
class InsideBeforeModel
|
17
|
+
include Mongoid::Document
|
18
|
+
include Mongoid::History::Trackable
|
19
|
+
|
20
|
+
track_history on: :fields
|
21
|
+
|
22
|
+
field :foo
|
23
|
+
end
|
24
|
+
|
25
|
+
expect(InsideBeforeModel.tracked?(:foo)).to be true
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should track fields when track_history called inside class and after fields' do
|
29
|
+
class InsideAfterModel
|
30
|
+
include Mongoid::Document
|
31
|
+
include Mongoid::History::Trackable
|
32
|
+
|
33
|
+
field :foo
|
34
|
+
|
35
|
+
track_history on: :fields
|
36
|
+
end
|
37
|
+
|
38
|
+
expect(InsideAfterModel.tracked?(:foo)).to be true
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should track fields when track_history called outside class' do
|
42
|
+
class OutsideModel
|
43
|
+
include Mongoid::Document
|
44
|
+
include Mongoid::History::Trackable
|
45
|
+
|
46
|
+
field :foo
|
47
|
+
end
|
48
|
+
|
49
|
+
OutsideModel.track_history on: :fields
|
50
|
+
expect(OutsideModel.tracked?(:foo)).to be true
|
51
|
+
end
|
52
|
+
end
|