freerange_acts_as_versioned 0.8.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
|