freerange_acts_as_versioned 0.8.2 → 1.0.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/Gemfile +3 -3
- data/acts_as_versioned.gemspec +6 -7
- data/lib/acts_as_versioned.rb +110 -133
- metadata +49 -66
data/Gemfile
CHANGED
data/acts_as_versioned.gemspec
CHANGED
|
@@ -7,20 +7,19 @@
|
|
|
7
7
|
Gem::Specification.new do |s|
|
|
8
8
|
s.specification_version = 2 if s.respond_to? :specification_version=
|
|
9
9
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
10
|
-
s.rubygems_version = '1.3.5'
|
|
11
10
|
|
|
12
11
|
## Leave these as is they will be modified for you by the rake gemspec task.
|
|
13
12
|
## If your rubyforge_project name is different, then edit it and comment out
|
|
14
13
|
## the sub! line in the Rakefile
|
|
15
14
|
s.name = 'freerange_acts_as_versioned'
|
|
16
|
-
s.version = '0.
|
|
17
|
-
s.date = '
|
|
15
|
+
s.version = '1.0.0'
|
|
16
|
+
s.date = '2013-08-15'
|
|
18
17
|
s.rubyforge_project = 'freerange_acts_as_versioned'
|
|
19
18
|
|
|
20
19
|
## Make sure your summary is short. The description may be as long
|
|
21
20
|
## as you like.
|
|
22
|
-
s.summary = "Add simple versioning to ActiveRecord models. This version supports rails 3.
|
|
23
|
-
s.description = "Add simple versioning to ActiveRecord models. rails 3.
|
|
21
|
+
s.summary = "Add simple versioning to ActiveRecord models. This version supports rails 3.2. Also it have support for autosave. It introduces new method auto_save_version which keeps 1 autosave version for an object."
|
|
22
|
+
s.description = "Add simple versioning to ActiveRecord models. rails 3.2"
|
|
24
23
|
|
|
25
24
|
## List the primary authors. If there are a bunch of authors, it's probably
|
|
26
25
|
## better to set the email to an email list or something. If you don't have
|
|
@@ -40,7 +39,7 @@ Gem::Specification.new do |s|
|
|
|
40
39
|
|
|
41
40
|
## List your runtime dependencies here. Runtime dependencies are those
|
|
42
41
|
## that are needed for an end user to actually USE your code.
|
|
43
|
-
s.add_dependency('activerecord', ["~> 3.
|
|
42
|
+
s.add_dependency('activerecord', ["~> 3.2"])
|
|
44
43
|
|
|
45
44
|
## List your development dependencies here. Development dependencies are
|
|
46
45
|
## those that are only needed during development
|
|
@@ -82,4 +81,4 @@ Gem::Specification.new do |s|
|
|
|
82
81
|
## Test files will be grabbed from the file list. Make sure the path glob
|
|
83
82
|
## matches what you actually use.
|
|
84
83
|
s.test_files = s.files.select { |path| path =~ /^test\/test_.*\.rb/ }
|
|
85
|
-
end
|
|
84
|
+
end
|
data/lib/acts_as_versioned.rb
CHANGED
|
@@ -67,7 +67,7 @@ module ActiveRecord #:nodoc:
|
|
|
67
67
|
#
|
|
68
68
|
# See ActiveRecord::Acts::Versioned::ClassMethods#acts_as_versioned for configuration options
|
|
69
69
|
module Versioned
|
|
70
|
-
VERSION = "0.
|
|
70
|
+
VERSION = "1.0.0"
|
|
71
71
|
CALLBACKS = [:set_new_version, :save_version, :save_version?]
|
|
72
72
|
|
|
73
73
|
# == Configuration options
|
|
@@ -249,12 +249,12 @@ module ActiveRecord #:nodoc:
|
|
|
249
249
|
|
|
250
250
|
versioned_class.cattr_accessor :original_class
|
|
251
251
|
versioned_class.original_class = self
|
|
252
|
-
versioned_class.
|
|
252
|
+
versioned_class.table_name = versioned_table_name
|
|
253
253
|
versioned_class.belongs_to self.to_s.demodulize.underscore.to_sym,
|
|
254
254
|
:class_name => "::#{self.to_s}",
|
|
255
255
|
:foreign_key => versioned_foreign_key
|
|
256
256
|
versioned_class.send :include, options[:extend] if options[:extend].is_a?(Module)
|
|
257
|
-
versioned_class.
|
|
257
|
+
versioned_class.sequence_name = version_sequence_name if version_sequence_name
|
|
258
258
|
end
|
|
259
259
|
|
|
260
260
|
module Behaviors
|
|
@@ -268,158 +268,136 @@ module ActiveRecord #:nodoc:
|
|
|
268
268
|
after_save :clear_old_versions
|
|
269
269
|
end
|
|
270
270
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
rev.save
|
|
281
|
-
end
|
|
282
|
-
end
|
|
283
|
-
|
|
284
|
-
# Saves a version of the model in the versioned table. This is called in the after_save callback by default
|
|
285
|
-
def auto_save_version
|
|
286
|
-
if @saving_version
|
|
287
|
-
@saving_version = nil
|
|
288
|
-
rev = self.class.versioned_class.new
|
|
289
|
-
clone_versioned_model(self, rev)
|
|
290
|
-
rev.send("#{self.class.version_column}=", send(self.class.version_column))
|
|
291
|
-
rev.send("#{self.class.versioned_foreign_key}=", id)
|
|
292
|
-
rev.send("autosave=", true)
|
|
293
|
-
saving_status = rev.save
|
|
294
|
-
clear_old_auto_save_versions
|
|
295
|
-
saving_status
|
|
296
|
-
end
|
|
271
|
+
# Saves a version of the model in the versioned table. This is called in the after_save callback by default
|
|
272
|
+
def save_version
|
|
273
|
+
if @saving_version
|
|
274
|
+
@saving_version = nil
|
|
275
|
+
rev = self.class.versioned_class.new
|
|
276
|
+
clone_versioned_model(self, rev)
|
|
277
|
+
rev.send("#{self.class.version_column}=", send(self.class.version_column))
|
|
278
|
+
rev.send("#{self.class.versioned_foreign_key}=", id)
|
|
279
|
+
rev.save
|
|
297
280
|
end
|
|
281
|
+
end
|
|
298
282
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
end
|
|
307
|
-
end
|
|
308
|
-
|
|
309
|
-
# Clears old revisions if a limit is set with the :limit option in <tt>acts_as_versioned</tt>.
|
|
310
|
-
# Override this method to set your own criteria for clearing old versions.
|
|
311
|
-
def clear_old_auto_save_versions
|
|
312
|
-
excess_baggage = self.class.versioned_class.where(["autosave = ? and #{self.class.versioned_foreign_key} = ?", true,id]).order("updated_at desc").all
|
|
313
|
-
if excess_baggage.length > 2
|
|
314
|
-
excess_baggage.last.destroy
|
|
315
|
-
end
|
|
283
|
+
# Clears old revisions if a limit is set with the :limit option in <tt>acts_as_versioned</tt>.
|
|
284
|
+
# Override this method to set your own criteria for clearing old versions.
|
|
285
|
+
def clear_old_versions
|
|
286
|
+
return if self.class.max_version_limit == 0
|
|
287
|
+
excess_baggage = send(self.class.version_column).to_i - self.class.max_version_limit
|
|
288
|
+
if excess_baggage > 0
|
|
289
|
+
self.class.versioned_class.delete_all ["#{self.class.version_column} <= ? and #{self.class.versioned_foreign_key} = ?", excess_baggage, id]
|
|
316
290
|
end
|
|
291
|
+
end
|
|
317
292
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
end
|
|
325
|
-
self.clone_versioned_model(version, self)
|
|
326
|
-
send("#{self.class.version_column}=", version.send(self.class.version_column))
|
|
327
|
-
true
|
|
293
|
+
# Reverts a model to a given version. Takes either a version number or an instance of the versioned model
|
|
294
|
+
def revert_to(version)
|
|
295
|
+
if version.is_a?(self.class.versioned_class)
|
|
296
|
+
return false unless version.send(self.class.versioned_foreign_key) == id and !version.new_record?
|
|
297
|
+
else
|
|
298
|
+
return false unless version = versions.where(self.class.version_column => version).first
|
|
328
299
|
end
|
|
300
|
+
self.clone_versioned_model(version, self)
|
|
301
|
+
send("#{self.class.version_column}=", version.send(self.class.version_column))
|
|
302
|
+
true
|
|
303
|
+
end
|
|
329
304
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
305
|
+
# Reverts a model to a given version and saves the model.
|
|
306
|
+
# Takes either a version number or an instance of the versioned model
|
|
307
|
+
def revert_to!(version)
|
|
308
|
+
revert_to(version) ? save_without_revision : false
|
|
309
|
+
end
|
|
335
310
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
311
|
+
# Temporarily turns off Optimistic Locking while saving. Used when reverting so that a new version is not created.
|
|
312
|
+
def save_without_revision
|
|
313
|
+
save_without_revision!
|
|
314
|
+
true
|
|
315
|
+
rescue
|
|
316
|
+
false
|
|
317
|
+
end
|
|
343
318
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
end
|
|
319
|
+
def save_without_revision!
|
|
320
|
+
without_locking do
|
|
321
|
+
without_revision do
|
|
322
|
+
save!
|
|
349
323
|
end
|
|
350
324
|
end
|
|
325
|
+
end
|
|
351
326
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
# Clones a model. Used when saving a new version or reverting a model's version.
|
|
357
|
-
def clone_versioned_model(orig_model, new_model)
|
|
358
|
-
self.class.versioned_columns.each do |col|
|
|
359
|
-
new_model[col.name] = orig_model.send(col.name) if orig_model.has_attribute?(col.name)
|
|
360
|
-
end
|
|
327
|
+
def altered?
|
|
328
|
+
track_altered_attributes ? (version_if_changed - changed).length < version_if_changed.length : changed?
|
|
329
|
+
end
|
|
361
330
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
end
|
|
331
|
+
# Clones a model. Used when saving a new version or reverting a model's version.
|
|
332
|
+
def clone_versioned_model(orig_model, new_model)
|
|
333
|
+
self.class.versioned_columns.each do |col|
|
|
334
|
+
new_model[col.name] = orig_model.send(col.name) if orig_model.has_attribute?(col.name)
|
|
367
335
|
end
|
|
368
336
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
337
|
+
clone_inheritance_column(orig_model, new_model)
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
def clone_inheritance_column(orig_model, new_model)
|
|
341
|
+
if orig_model.is_a?(self.class.versioned_class) && new_model.class.column_names.include?(new_model.class.inheritance_column.to_s)
|
|
342
|
+
new_model[new_model.class.inheritance_column] = orig_model[self.class.versioned_inheritance_column]
|
|
343
|
+
elsif new_model.is_a?(self.class.versioned_class) && new_model.class.column_names.include?(self.class.versioned_inheritance_column.to_s)
|
|
344
|
+
new_model[self.class.versioned_inheritance_column] = orig_model[orig_model.class.inheritance_column]
|
|
372
345
|
end
|
|
346
|
+
end
|
|
373
347
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
when version_condition.is_a?(Symbol)
|
|
379
|
-
send(version_condition)
|
|
380
|
-
when version_condition.respond_to?(:call) && (version_condition.arity == 1 || version_condition.arity == -1)
|
|
381
|
-
version_condition.call(self)
|
|
382
|
-
else
|
|
383
|
-
version_condition
|
|
384
|
-
end
|
|
385
|
-
end
|
|
348
|
+
# Checks whether a new version shall be saved or not. Calls <tt>version_condition_met?</tt> and <tt>changed?</tt>.
|
|
349
|
+
def save_version?
|
|
350
|
+
version_condition_met? && altered?
|
|
351
|
+
end
|
|
386
352
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
353
|
+
# Checks condition set in the :if option to check whether a revision should be created or not. Override this for
|
|
354
|
+
# custom version condition checking.
|
|
355
|
+
def version_condition_met?
|
|
356
|
+
case
|
|
357
|
+
when version_condition.is_a?(Symbol)
|
|
358
|
+
send(version_condition)
|
|
359
|
+
when version_condition.respond_to?(:call) && (version_condition.arity == 1 || version_condition.arity == -1)
|
|
360
|
+
version_condition.call(self)
|
|
361
|
+
else
|
|
362
|
+
version_condition
|
|
395
363
|
end
|
|
364
|
+
end
|
|
396
365
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
366
|
+
# Executes the block with the versioning callbacks disabled.
|
|
367
|
+
#
|
|
368
|
+
# @foo.without_revision do
|
|
369
|
+
# @foo.save
|
|
370
|
+
# end
|
|
371
|
+
#
|
|
372
|
+
def without_revision(&block)
|
|
373
|
+
self.class.without_revision(&block)
|
|
374
|
+
end
|
|
406
375
|
|
|
407
|
-
|
|
408
|
-
|
|
376
|
+
# Turns off optimistic locking for the duration of the block
|
|
377
|
+
#
|
|
378
|
+
# @foo.without_locking do
|
|
379
|
+
# @foo.save
|
|
380
|
+
# end
|
|
381
|
+
#
|
|
382
|
+
def without_locking(&block)
|
|
383
|
+
self.class.without_locking(&block)
|
|
384
|
+
end
|
|
409
385
|
|
|
410
|
-
|
|
386
|
+
def empty_callback()
|
|
387
|
+
end
|
|
411
388
|
|
|
412
|
-
|
|
413
|
-
# sets the new version before saving, unless you're using optimistic locking. In that case, let it take care of the version.
|
|
414
|
-
def set_new_version
|
|
415
|
-
@saving_version = new_record? || save_version?
|
|
416
|
-
self.send("#{self.class.version_column}=", next_version) if new_record? || (!locking_enabled? && save_version?)
|
|
417
|
-
end
|
|
389
|
+
#:nodoc:
|
|
418
390
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
391
|
+
protected
|
|
392
|
+
# sets the new version before saving, unless you're using optimistic locking. In that case, let it take care of the version.
|
|
393
|
+
def set_new_version
|
|
394
|
+
@saving_version = new_record? || save_version?
|
|
395
|
+
self.send("#{self.class.version_column}=", next_version) if new_record? || (!locking_enabled? && save_version?)
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
# Gets the next available version for the current record, or 1 for a new record
|
|
399
|
+
def next_version
|
|
400
|
+
(new_record? ? 0 : versions.calculate(:maximum, version_column).to_i) + 1
|
|
423
401
|
end
|
|
424
402
|
|
|
425
403
|
module ClassMethods
|
|
@@ -446,7 +424,6 @@ module ActiveRecord #:nodoc:
|
|
|
446
424
|
self.connection.create_table(versioned_table_name, create_table_options) do |t|
|
|
447
425
|
t.column versioned_foreign_key, :integer
|
|
448
426
|
t.column version_column, :integer
|
|
449
|
-
t.column :autosave, :boolean , :default => false
|
|
450
427
|
end
|
|
451
428
|
|
|
452
429
|
self.versioned_columns.each do |col|
|
metadata
CHANGED
|
@@ -1,66 +1,57 @@
|
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: freerange_acts_as_versioned
|
|
3
|
-
version: !ruby/object:Gem::Version
|
|
4
|
-
|
|
5
|
-
prerelease:
|
|
6
|
-
segments:
|
|
7
|
-
- 0
|
|
8
|
-
- 8
|
|
9
|
-
- 2
|
|
10
|
-
version: 0.8.2
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
prerelease:
|
|
11
6
|
platform: ruby
|
|
12
|
-
authors:
|
|
7
|
+
authors:
|
|
13
8
|
- Abdul Rauf
|
|
14
9
|
autorequire:
|
|
15
10
|
bindir: bin
|
|
16
11
|
cert_chain: []
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
dependencies:
|
|
21
|
-
- !ruby/object:Gem::Dependency
|
|
12
|
+
date: 2013-08-15 00:00:00.000000000 Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
22
15
|
name: activerecord
|
|
23
|
-
|
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
|
25
17
|
none: false
|
|
26
|
-
requirements:
|
|
18
|
+
requirements:
|
|
27
19
|
- - ~>
|
|
28
|
-
- !ruby/object:Gem::Version
|
|
29
|
-
|
|
30
|
-
segments:
|
|
31
|
-
- 3
|
|
32
|
-
- 1
|
|
33
|
-
- 1
|
|
34
|
-
version: 3.1.1
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '3.2'
|
|
35
22
|
type: :runtime
|
|
36
|
-
version_requirements: *id001
|
|
37
|
-
- !ruby/object:Gem::Dependency
|
|
38
|
-
name: sqlite3-ruby
|
|
39
23
|
prerelease: false
|
|
40
|
-
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ~>
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: '3.2'
|
|
30
|
+
- !ruby/object:Gem::Dependency
|
|
31
|
+
name: sqlite3-ruby
|
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
|
41
33
|
none: false
|
|
42
|
-
requirements:
|
|
34
|
+
requirements:
|
|
43
35
|
- - ~>
|
|
44
|
-
- !ruby/object:Gem::Version
|
|
45
|
-
hash: 25
|
|
46
|
-
segments:
|
|
47
|
-
- 1
|
|
48
|
-
- 3
|
|
49
|
-
- 1
|
|
36
|
+
- !ruby/object:Gem::Version
|
|
50
37
|
version: 1.3.1
|
|
51
38
|
type: :development
|
|
52
|
-
|
|
53
|
-
|
|
39
|
+
prerelease: false
|
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
41
|
+
none: false
|
|
42
|
+
requirements:
|
|
43
|
+
- - ~>
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: 1.3.1
|
|
46
|
+
description: Add simple versioning to ActiveRecord models. rails 3.2
|
|
54
47
|
email: abdul.rauf.au@gmail.com
|
|
55
48
|
executables: []
|
|
56
|
-
|
|
57
49
|
extensions: []
|
|
58
|
-
|
|
59
|
-
extra_rdoc_files:
|
|
50
|
+
extra_rdoc_files:
|
|
60
51
|
- README
|
|
61
52
|
- MIT-LICENSE
|
|
62
53
|
- CHANGELOG
|
|
63
|
-
files:
|
|
54
|
+
files:
|
|
64
55
|
- CHANGELOG
|
|
65
56
|
- Gemfile
|
|
66
57
|
- MIT-LICENSE
|
|
@@ -86,39 +77,31 @@ files:
|
|
|
86
77
|
- test/migration_test.rb
|
|
87
78
|
- test/schema.rb
|
|
88
79
|
- test/versioned_test.rb
|
|
89
|
-
has_rdoc: true
|
|
90
80
|
homepage: http://github.com/abdulrauf/acts_as_versioned
|
|
91
81
|
licenses: []
|
|
92
|
-
|
|
93
82
|
post_install_message:
|
|
94
|
-
rdoc_options:
|
|
83
|
+
rdoc_options:
|
|
95
84
|
- --charset=UTF-8
|
|
96
|
-
require_paths:
|
|
85
|
+
require_paths:
|
|
97
86
|
- lib
|
|
98
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
|
87
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
99
88
|
none: false
|
|
100
|
-
requirements:
|
|
101
|
-
- -
|
|
102
|
-
- !ruby/object:Gem::Version
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
- 0
|
|
106
|
-
version: "0"
|
|
107
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
89
|
+
requirements:
|
|
90
|
+
- - ! '>='
|
|
91
|
+
- !ruby/object:Gem::Version
|
|
92
|
+
version: '0'
|
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
108
94
|
none: false
|
|
109
|
-
requirements:
|
|
110
|
-
- -
|
|
111
|
-
- !ruby/object:Gem::Version
|
|
112
|
-
|
|
113
|
-
segments:
|
|
114
|
-
- 0
|
|
115
|
-
version: "0"
|
|
95
|
+
requirements:
|
|
96
|
+
- - ! '>='
|
|
97
|
+
- !ruby/object:Gem::Version
|
|
98
|
+
version: '0'
|
|
116
99
|
requirements: []
|
|
117
|
-
|
|
118
100
|
rubyforge_project: freerange_acts_as_versioned
|
|
119
|
-
rubygems_version: 1.
|
|
101
|
+
rubygems_version: 1.8.25
|
|
120
102
|
signing_key:
|
|
121
103
|
specification_version: 2
|
|
122
|
-
summary: Add simple versioning to ActiveRecord models. This version supports rails
|
|
104
|
+
summary: Add simple versioning to ActiveRecord models. This version supports rails
|
|
105
|
+
3.2. Also it have support for autosave. It introduces new method auto_save_version
|
|
106
|
+
which keeps 1 autosave version for an object.
|
|
123
107
|
test_files: []
|
|
124
|
-
|