acts_as_revisionable 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,10 +5,6 @@ module ActsAsRevisionable
5
5
 
6
6
  autoload :RevisionRecord, File.expand_path('../acts_as_revisionable/revision_record', __FILE__)
7
7
 
8
- def self.included(base)
9
- base.extend(ActsMethods)
10
- end
11
-
12
8
  module ActsMethods
13
9
  # Calling acts_as_revisionable will inject the revisionable behavior into the class. Specifying a :limit option
14
10
  # will limit the number of revisions that are kept per record. Specifying :minimum_age will ensure that revisions are
@@ -39,6 +35,11 @@ module ActsAsRevisionable
39
35
  # :version => 1
40
36
  # }
41
37
  #
38
+ # As a shortcut, you can can also just pass an attribute name or array of attribute names to copy to the revision
39
+ # record.
40
+ #
41
+ # acts_as_revisionable :meta => :updated_by
42
+ #
42
43
  # The values to the <tt>:meta</tt> hash can be either symbols or Procs. If it is a symbol, the method
43
44
  # so named will be called on the record being revisioned. If it is a Proc, it will be called with the
44
45
  # record as the argument. Any other class will be sent directly to the revision record.
@@ -57,7 +58,6 @@ module ActsAsRevisionable
57
58
  acts_as_revisionable_options[:class_name] = acts_as_revisionable_options[:class_name].name if acts_as_revisionable_options[:class_name].is_a?(Class)
58
59
  extend ClassMethods
59
60
  include InstanceMethods
60
- class_name =
61
61
  class_name = acts_as_revisionable_options[:class_name].to_s if acts_as_revisionable_options[:class_name]
62
62
  has_many_options = {:as => :revisionable, :order => 'revision DESC', :class_name => class_name}
63
63
  has_many_options[:dependent] = :destroy unless options[:dependent] == :keep
@@ -217,7 +217,6 @@ module ActsAsRevisionable
217
217
  truncate_revisions!
218
218
  end
219
219
  rescue => e
220
- puts e
221
220
  logger.warn(e) if logger
222
221
  end
223
222
 
@@ -235,7 +234,6 @@ module ActsAsRevisionable
235
234
  begin
236
235
  revision.destroy
237
236
  rescue => e
238
- puts e
239
237
  logger.warn(e) if logger
240
238
  end
241
239
  end
@@ -247,17 +245,18 @@ module ActsAsRevisionable
247
245
 
248
246
  # Create a revision record based on this record and save it to the database.
249
247
  def create_revision!
250
- revision = revision_record_class.new(self, acts_as_revisionable_options[:encoding])
251
- if self.acts_as_revisionable_options[:meta].is_a?(Hash)
252
- self.acts_as_revisionable_options[:meta].each do |attribute, value|
253
- case value
254
- when Symbol
255
- value = self.send(value)
256
- when Proc
257
- value = value.call(self)
258
- end
259
- revision.send("#{attribute}=", value)
248
+ revision_options = self.class.acts_as_revisionable_options
249
+ revision = revision_record_class.new(self, revision_options[:encoding])
250
+ if revision_options[:meta].is_a?(Hash)
251
+ revision_options[:meta].each do |attribute, value|
252
+ set_revision_meta_attribute(revision, attribute, value)
260
253
  end
254
+ elsif revision_options[:meta].is_a?(Array)
255
+ revision_options[:meta].each do |attribute|
256
+ set_revision_meta_attribute(revision, attribute, attribute.to_sym)
257
+ end
258
+ elsif revision_options[:meta]
259
+ set_revision_meta_attribute(revision, revision_options[:meta], revision_options[:meta].to_sym)
261
260
  end
262
261
  revision.save!
263
262
  return revision
@@ -265,7 +264,7 @@ module ActsAsRevisionable
265
264
 
266
265
  # Truncate the number of revisions kept for this record. Available options are :limit and :minimum_age.
267
266
  def truncate_revisions!(options = nil)
268
- options = {:limit => acts_as_revisionable_options[:limit], :minimum_age => acts_as_revisionable_options[:minimum_age]} unless options
267
+ options = {:limit => self.class.acts_as_revisionable_options[:limit], :minimum_age => self.class.acts_as_revisionable_options[:minimum_age]} unless options
269
268
  revision_record_class.truncate_revisions(self.class, self.id, options)
270
269
  end
271
270
 
@@ -301,7 +300,18 @@ module ActsAsRevisionable
301
300
  update_without_revision
302
301
  end
303
302
  end
303
+
304
+ # Set an attribute based on a meta argument
305
+ def set_revision_meta_attribute(revision, attribute, value)
306
+ case value
307
+ when Symbol
308
+ value = self.send(value)
309
+ when Proc
310
+ value = value.call(self)
311
+ end
312
+ revision.send("#{attribute}=", value)
313
+ end
304
314
  end
305
315
  end
306
316
 
307
- ActiveRecord::Base.send(:include, ActsAsRevisionable)
317
+ ActiveRecord::Base.extend(ActsAsRevisionable::ActsMethods)
@@ -143,7 +143,7 @@ describe ActsAsRevisionable do
143
143
 
144
144
  context "injected methods" do
145
145
  it "should be able to inject revisionable behavior onto ActiveRecord::Base" do
146
- ActiveRecord::Base.included_modules.should include(ActsAsRevisionable)
146
+ ActiveRecord::Base.should respond_to(:acts_as_revisionable)
147
147
  end
148
148
 
149
149
  it "should add as has_many :record_revisions association" do
@@ -275,8 +275,8 @@ describe ActsAsRevisionable do
275
275
  record_1.create_revision!
276
276
  ActsAsRevisionable::RevisionRecord.count.should == 1
277
277
  end
278
-
279
- it "should set metadata on the revison when creating a revision record" do
278
+
279
+ it "should set metadata on the revison when creating a revision record using a complex attribute to value mapping" do
280
280
  record_1 = OtherRevisionableTestModel.create!(:name => "test", :updated_by => "dude")
281
281
  RevisionRecord2.count.should == 0
282
282
  record_1.create_revision!
@@ -286,6 +286,38 @@ describe ActsAsRevisionable do
286
286
  revision.updated_by.should == "dude"
287
287
  revision.version.should == 1
288
288
  end
289
+
290
+ it "should set metadata on the revison when creating a revision record using a simply string to define a method to copy" do
291
+ meta_value = OtherRevisionableTestModel.acts_as_revisionable_options[:meta]
292
+ begin
293
+ OtherRevisionableTestModel.acts_as_revisionable_options[:meta] = "label"
294
+ record_1 = OtherRevisionableTestModel.create!(:name => "test", :updated_by => "dude")
295
+ record_1.stub!(:label => "this is a label")
296
+ record_1.create_revision!
297
+ revision = record_1.last_revision
298
+ revision.label.should == "this is a label"
299
+ revision.updated_by.should == nil
300
+ revision.version.should == nil
301
+ ensure
302
+ OtherRevisionableTestModel.acts_as_revisionable_options[:meta] = meta_value
303
+ end
304
+ end
305
+
306
+ it "should set metadata on the revison when creating a revision record using an array of attribute names to copy" do
307
+ meta_value = OtherRevisionableTestModel.acts_as_revisionable_options[:meta]
308
+ begin
309
+ OtherRevisionableTestModel.acts_as_revisionable_options[:meta] = [:label, "version"]
310
+ record_1 = OtherRevisionableTestModel.create!(:name => "test", :updated_by => "dude")
311
+ record_1.stub!(:label => "this is a label", :version => 100)
312
+ record_1.create_revision!
313
+ revision = record_1.last_revision
314
+ revision.label.should == "this is a label"
315
+ revision.updated_by.should == nil
316
+ revision.version.should == 100
317
+ ensure
318
+ OtherRevisionableTestModel.acts_as_revisionable_options[:meta] = meta_value
319
+ end
320
+ end
289
321
 
290
322
  it "should not create a revision entry if revisioning is disabled" do
291
323
  record = RevisionableTestModel.create!(:name => "test")
@@ -322,7 +354,7 @@ describe ActsAsRevisionable do
322
354
  end
323
355
  model.reload
324
356
  ActsAsRevisionable::RevisionRecord.count.should == 0
325
-
357
+
326
358
  model.should_receive(:update).and_raise("update failed")
327
359
  model.name = 'new_name'
328
360
  begin
@@ -334,7 +366,7 @@ describe ActsAsRevisionable do
334
366
  end
335
367
  ActsAsRevisionable::RevisionRecord.count.should == 0
336
368
  end
337
-
369
+
338
370
  it "should not save a revision if an update fails with errors" do
339
371
  model = RevisionableTestModel.new(:name => 'test')
340
372
  model.store_revision do
@@ -342,7 +374,7 @@ describe ActsAsRevisionable do
342
374
  end
343
375
  model.reload
344
376
  ActsAsRevisionable::RevisionRecord.count.should == 0
345
-
377
+
346
378
  model.name = 'new_name'
347
379
  model.store_revision do
348
380
  ActsAsRevisionable::RevisionRecord.count.should == 1
@@ -351,7 +383,7 @@ describe ActsAsRevisionable do
351
383
  end
352
384
  ActsAsRevisionable::RevisionRecord.count.should == 0
353
385
  end
354
-
386
+
355
387
  it "should mark the last revision for a deleted record as being trash" do
356
388
  model = ActsAsRevisionable::RevisionableNamespaceModel.new(:name => 'test')
357
389
  model.save!
@@ -364,7 +396,7 @@ describe ActsAsRevisionable do
364
396
  ActsAsRevisionable::RevisionRecord.last_revision(ActsAsRevisionable::RevisionableNamespaceModel, model.id).should be_trash
365
397
  end
366
398
  end
367
-
399
+
368
400
  context "restoring revisions" do
369
401
  it "should restore a record without associations" do
370
402
  model = RevisionableTestModel.new(:name => 'test')
@@ -374,7 +406,7 @@ describe ActsAsRevisionable do
374
406
  end
375
407
  model.reload
376
408
  ActsAsRevisionable::RevisionRecord.count.should == 0
377
-
409
+
378
410
  model.name = 'new_name'
379
411
  model.set_secret(5678)
380
412
  model.store_revision do
@@ -384,12 +416,12 @@ describe ActsAsRevisionable do
384
416
  ActsAsRevisionable::RevisionRecord.count.should == 1
385
417
  model.name.should == 'new_name'
386
418
  model.secret.should == 5678
387
-
419
+
388
420
  restored = model.restore_revision(1)
389
421
  restored.name.should == 'test'
390
422
  restored.secret.should == 1234
391
423
  restored.id.should == model.id
392
-
424
+
393
425
  restored.store_revision do
394
426
  restored.save!
395
427
  end
@@ -399,12 +431,12 @@ describe ActsAsRevisionable do
399
431
  restored_model.name.should == restored.name
400
432
  restored_model.secret.should == restored.secret
401
433
  end
402
-
434
+
403
435
  it "should restore a record with has_many associations" do
404
436
  many_thing_1 = RevisionableTestManyThing.new(:name => 'many_thing_1')
405
437
  many_thing_1.sub_things.build(:name => 'sub_thing_1')
406
438
  many_thing_1.sub_things.build(:name => 'sub_thing_2')
407
-
439
+
408
440
  model = RevisionableTestModel.new(:name => 'test')
409
441
  model.many_things << many_thing_1
410
442
  model.many_things.build(:name => 'many_thing_2')
@@ -416,7 +448,7 @@ describe ActsAsRevisionable do
416
448
  RevisionableTestSubThing.count.should == 2
417
449
  RevisionableTestManyOtherThing.count.should == 2
418
450
  ActsAsRevisionable::RevisionRecord.count.should == 0
419
-
451
+
420
452
  model.store_revision do
421
453
  model.name = 'new_name'
422
454
  many_thing_1 = model.many_things.detect{|t| t.name == 'many_thing_1'}
@@ -439,7 +471,7 @@ describe ActsAsRevisionable do
439
471
  sub_thing_1.save!
440
472
  many_other_thing_1.save!
441
473
  end
442
-
474
+
443
475
  model.reload
444
476
  ActsAsRevisionable::RevisionRecord.count.should == 1
445
477
  RevisionableTestManyThing.count.should == 2
@@ -449,7 +481,7 @@ describe ActsAsRevisionable do
449
481
  model.many_things.collect{|t| t.name}.sort.should == ['many_thing_3', 'new_many_thing_1']
450
482
  model.many_things.detect{|t| t.name == 'new_many_thing_1'}.sub_things.collect{|t| t.name}.sort.should == ['new_sub_thing_1', 'sub_thing_3']
451
483
  model.many_other_things.collect{|t| t.name}.sort.should == ['many_other_thing_3', 'new_many_other_thing_1']
452
-
484
+
453
485
  # restore to memory
454
486
  restored = model.restore_revision(1)
455
487
  restored.name.should == 'test'
@@ -458,14 +490,14 @@ describe ActsAsRevisionable do
458
490
  restored.many_things.detect{|t| t.name == 'many_thing_1'}.sub_things.collect{|t| t.name}.sort.should == ['sub_thing_1', 'sub_thing_2']
459
491
  restored.many_other_things.collect{|t| t.name}.sort.should == ['many_other_thing_3', 'new_many_other_thing_1']
460
492
  restored.valid?.should == true
461
-
493
+
462
494
  # make the restore to memory didn't affect the database
463
495
  model.reload
464
496
  model.name.should == 'new_name'
465
497
  model.many_things(true).collect{|t| t.name}.sort.should == ['many_thing_3', 'new_many_thing_1']
466
498
  model.many_things.detect{|t| t.name == 'new_many_thing_1'}.sub_things.collect{|t| t.name}.sort.should == ['new_sub_thing_1', 'sub_thing_3']
467
499
  model.many_other_things.collect{|t| t.name}.sort.should == ['many_other_thing_3', 'new_many_other_thing_1']
468
-
500
+
469
501
  model.restore_revision!(1)
470
502
  RevisionableTestModel.count.should == 1
471
503
  RevisionableTestManyThing.count.should == 2
@@ -479,7 +511,7 @@ describe ActsAsRevisionable do
479
511
  restored.many_things.detect{|t| t.name == 'many_thing_2'}.sub_things.collect{|t| t.name}.sort.should == []
480
512
  restored.many_other_things.collect{|t| t.name}.sort.should == ['many_other_thing_3', 'new_many_other_thing_1']
481
513
  end
482
-
514
+
483
515
  it "should restore a record with has_one associations" do
484
516
  model = RevisionableTestModel.new(:name => 'test')
485
517
  model.build_one_thing(:name => 'other')
data/spec/spec_helper.rb CHANGED
@@ -19,7 +19,7 @@ if ActiveRecord::VERSION::MAJOR >= 3
19
19
  if ActiveRecord::VERSION::MINOR == 0
20
20
  composite_primary_key_version = "~>3.1.0"
21
21
  else
22
- composite_primary_key_version = "~>4.0.0.a"
22
+ composite_primary_key_version = ">=4.0.0"
23
23
  end
24
24
  else
25
25
  composite_primary_key_version = "~>2.3.5"
metadata CHANGED
@@ -1,198 +1,80 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: acts_as_revisionable
3
- version: !ruby/object:Gem::Version
4
- hash: 31
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.2.1
5
5
  prerelease:
6
- segments:
7
- - 1
8
- - 2
9
- - 0
10
- version: 1.2.0
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Brian Durand
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-08-05 00:00:00 -05:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
22
- name: rake
23
- version_requirements: &id001 !ruby/object:Gem::Requirement
24
- none: false
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- hash: 3
29
- segments:
30
- - 0
31
- version: "0"
32
- prerelease: false
33
- type: :runtime
34
- requirement: *id001
35
- - !ruby/object:Gem::Dependency
36
- name: rspec
37
- version_requirements: &id002 !ruby/object:Gem::Requirement
38
- none: false
39
- requirements:
40
- - - ">="
41
- - !ruby/object:Gem::Version
42
- hash: 23
43
- segments:
44
- - 2
45
- - 6
46
- - 0
47
- version: 2.6.0
48
- prerelease: false
49
- type: :runtime
50
- requirement: *id002
51
- - !ruby/object:Gem::Dependency
12
+ date: 2011-11-22 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
52
15
  name: activerecord
53
- version_requirements: &id003 !ruby/object:Gem::Requirement
16
+ requirement: &2161226620 !ruby/object:Gem::Requirement
54
17
  none: false
55
- requirements:
56
- - - ~>
57
- - !ruby/object:Gem::Version
58
- hash: 17
59
- segments:
60
- - 2
61
- - 3
62
- - 9
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
63
21
  version: 2.3.9
64
- prerelease: false
65
22
  type: :runtime
66
- requirement: *id003
67
- - !ruby/object:Gem::Dependency
68
- name: activesupport
69
- version_requirements: &id004 !ruby/object:Gem::Requirement
70
- none: false
71
- requirements:
72
- - - ~>
73
- - !ruby/object:Gem::Version
74
- hash: 17
75
- segments:
76
- - 2
77
- - 3
78
- - 9
79
- version: 2.3.9
80
23
  prerelease: false
81
- type: :runtime
82
- requirement: *id004
83
- - !ruby/object:Gem::Dependency
24
+ version_requirements: *2161226620
25
+ - !ruby/object:Gem::Dependency
84
26
  name: composite_primary_keys
85
- version_requirements: &id005 !ruby/object:Gem::Requirement
27
+ requirement: &2161226000 !ruby/object:Gem::Requirement
86
28
  none: false
87
- requirements:
88
- - - ">="
89
- - !ruby/object:Gem::Version
90
- hash: 3
91
- segments:
92
- - 0
93
- version: "0"
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
94
34
  prerelease: false
95
- type: :runtime
96
- requirement: *id005
97
- - !ruby/object:Gem::Dependency
35
+ version_requirements: *2161226000
36
+ - !ruby/object:Gem::Dependency
98
37
  name: sqlite3
99
- version_requirements: &id006 !ruby/object:Gem::Requirement
100
- none: false
101
- requirements:
102
- - - ~>
103
- - !ruby/object:Gem::Version
104
- hash: 19
105
- segments:
106
- - 1
107
- - 3
108
- - 4
109
- version: 1.3.4
110
- prerelease: false
111
- type: :runtime
112
- requirement: *id006
113
- - !ruby/object:Gem::Dependency
114
- name: activerecord
115
- version_requirements: &id007 !ruby/object:Gem::Requirement
116
- none: false
117
- requirements:
118
- - - ">="
119
- - !ruby/object:Gem::Version
120
- hash: 17
121
- segments:
122
- - 2
123
- - 3
124
- - 9
125
- version: 2.3.9
126
- prerelease: false
127
- type: :runtime
128
- requirement: *id007
129
- - !ruby/object:Gem::Dependency
130
- name: composite_primary_keys
131
- version_requirements: &id008 !ruby/object:Gem::Requirement
38
+ requirement: &2161225440 !ruby/object:Gem::Requirement
132
39
  none: false
133
- requirements:
134
- - - ">="
135
- - !ruby/object:Gem::Version
136
- hash: 3
137
- segments:
138
- - 0
139
- version: "0"
140
- prerelease: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
141
44
  type: :development
142
- requirement: *id008
143
- - !ruby/object:Gem::Dependency
144
- name: sqlite3
145
- version_requirements: &id009 !ruby/object:Gem::Requirement
146
- none: false
147
- requirements:
148
- - - ">="
149
- - !ruby/object:Gem::Version
150
- hash: 3
151
- segments:
152
- - 0
153
- version: "0"
154
45
  prerelease: false
155
- type: :development
156
- requirement: *id009
157
- - !ruby/object:Gem::Dependency
46
+ version_requirements: *2161225440
47
+ - !ruby/object:Gem::Dependency
158
48
  name: rspec
159
- version_requirements: &id010 !ruby/object:Gem::Requirement
49
+ requirement: &2161224920 !ruby/object:Gem::Requirement
160
50
  none: false
161
- requirements:
162
- - - ">="
163
- - !ruby/object:Gem::Version
164
- hash: 15
165
- segments:
166
- - 2
167
- - 0
168
- - 0
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
169
54
  version: 2.0.0
170
- prerelease: false
171
55
  type: :development
172
- requirement: *id010
173
- - !ruby/object:Gem::Dependency
56
+ prerelease: false
57
+ version_requirements: *2161224920
58
+ - !ruby/object:Gem::Dependency
174
59
  name: jeweler
175
- version_requirements: &id011 !ruby/object:Gem::Requirement
60
+ requirement: &2161224300 !ruby/object:Gem::Requirement
176
61
  none: false
177
- requirements:
178
- - - ">="
179
- - !ruby/object:Gem::Version
180
- hash: 3
181
- segments:
182
- - 0
183
- version: "0"
184
- prerelease: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
185
66
  type: :development
186
- requirement: *id011
187
- description: ActiveRecord extension that provides revision support so that history can be tracked and changes can be reverted. Emphasis for this plugin versus similar ones is including associations, saving on storage, and extensibility of the model.
67
+ prerelease: false
68
+ version_requirements: *2161224300
69
+ description: ActiveRecord extension that provides revision support so that history
70
+ can be tracked and changes can be reverted. Emphasis for this plugin versus similar
71
+ ones is including associations, saving on storage, and extensibility of the model.
188
72
  email: brian@embellishedvisions.com
189
73
  executables: []
190
-
191
74
  extensions: []
192
-
193
- extra_rdoc_files:
75
+ extra_rdoc_files:
194
76
  - README.rdoc
195
- files:
77
+ files:
196
78
  - MIT-LICENSE
197
79
  - README.rdoc
198
80
  - Rakefile
@@ -202,39 +84,29 @@ files:
202
84
  - spec/revision_record_spec.rb
203
85
  - spec/spec_helper.rb
204
86
  - spec/version_1_1_upgrade_spec.rb
205
- has_rdoc: true
206
87
  homepage: http://github.com/bdurand/acts_as_revisionable
207
88
  licenses: []
208
-
209
89
  post_install_message:
210
90
  rdoc_options: []
211
-
212
- require_paths:
91
+ require_paths:
213
92
  - lib
214
- required_ruby_version: !ruby/object:Gem::Requirement
93
+ required_ruby_version: !ruby/object:Gem::Requirement
215
94
  none: false
216
- requirements:
217
- - - ">="
218
- - !ruby/object:Gem::Version
219
- hash: 3
220
- segments:
221
- - 0
222
- version: "0"
223
- required_rubygems_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
224
100
  none: false
225
- requirements:
226
- - - ">="
227
- - !ruby/object:Gem::Version
228
- hash: 3
229
- segments:
230
- - 0
231
- version: "0"
101
+ requirements:
102
+ - - ! '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
232
105
  requirements: []
233
-
234
106
  rubyforge_project:
235
- rubygems_version: 1.5.2
107
+ rubygems_version: 1.8.10
236
108
  signing_key:
237
109
  specification_version: 3
238
- summary: ActiveRecord extension that provides revision support so that history can be tracked and changes can be reverted.
110
+ summary: ActiveRecord extension that provides revision support so that history can
111
+ be tracked and changes can be reverted.
239
112
  test_files: []
240
-