rtiss_acts_as_versioned 0.8.2 → 0.8.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cac92ff6342270205cab079fb0f7ce7dba50bbd0
4
- data.tar.gz: 2130ecc8fb34f759ddcf46dcabce01e349903ab8
3
+ metadata.gz: b9f5a6e965b68027705381bc7f298c863c4a72f1
4
+ data.tar.gz: d604439b36e5bd52fe5480dcf5e96a1a74c6f213
5
5
  SHA512:
6
- metadata.gz: 860ff36bcf176300a9af52127515c6ee61534a7a6f039c75046d836e6c1624b09c046033756a9f10cd7c0a10802b96ede5bb6f7d6d4765fb0ece1e3c1e11c538
7
- data.tar.gz: f17c24bc136814c0e84db5a44486add1131a0f87e1d559e6bc9c56c3de694319e8cf703a8294d126f941d755b8754611414e67ea04052f8e2305a74b42ccf707
6
+ metadata.gz: 59bcc2984591245b9dcfafde7e80330388fdff93ca952ba582b3759941dc5c575bc64ea13f7ceff5b6685ae5dcba10273d24bad8839e63ff8afb409b372bb1ea
7
+ data.tar.gz: e180bd6b6234db9488ce3e9beb9f40b2c4521e57161ab89346cd96b786208822c7340d64f6c9751fce5743f6cfa516b8920b2b8669b37867dfeaf183cd2fc71a
data/Rakefile CHANGED
@@ -73,14 +73,6 @@ task :console do
73
73
  sh "irb -rubygems -r ./lib//#{name}.rb"
74
74
  end
75
75
 
76
- #############################################################################
77
- #
78
- # Custom tasks (add your own tasks here)
79
- #
80
- #############################################################################
81
-
82
-
83
-
84
76
  #############################################################################
85
77
  #
86
78
  # Packaging tasks
@@ -20,7 +20,7 @@
20
20
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
21
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
22
 
23
- VERSION = '0.8.2'
23
+ VERSION = '0.8.3'
24
24
 
25
25
  module ActiveRecord #:nodoc:
26
26
  module Acts #:nodoc:
@@ -173,7 +173,7 @@ module ActiveRecord #:nodoc:
173
173
 
174
174
  cattr_accessor :versioned_class_name, :versioned_foreign_key, :versioned_table_name, :versioned_inheritance_column,
175
175
  :version_column, :max_version_limit, :track_altered_attributes, :version_condition, :version_sequence_name, :non_versioned_columns,
176
- :version_association_options, :version_if_changed, :deleted_in_original_table_flag, :record_restored_flag
176
+ :version_association_options, :version_if_changed, :deleted_in_original_table_flag, :record_restored_column
177
177
 
178
178
  self.versioned_class_name = options[:class_name] || "Version"
179
179
  self.versioned_foreign_key = options[:foreign_key] || self.to_s.foreign_key
@@ -182,11 +182,14 @@ module ActiveRecord #:nodoc:
182
182
  self.versioned_inheritance_column = options[:inheritance_column] || "versioned_#{inheritance_column}"
183
183
  self.version_column = options[:version_column] || 'version'
184
184
  self.deleted_in_original_table_flag = options[:deleted_in_original_table_flag] || 'deleted_in_original_table'
185
- self.record_restored_flag = options[:record_restored_flag] || 'record_restored'
185
+ self.record_restored_column = options[:record_restored_column] || 'record_restored'
186
186
  self.version_sequence_name = options[:sequence_name]
187
187
  self.max_version_limit = options[:limit].to_i
188
188
  self.version_condition = options[:if] || true
189
189
  self.non_versioned_columns = [self.primary_key, inheritance_column, self.version_column, 'lock_version', versioned_inheritance_column] + options[:non_versioned_columns].to_a.map(&:to_s)
190
+ if options[:association_options].is_a?(Hash) && options[:association_options][:dependent] == :nullify
191
+ raise "Illegal option :dependent => :nullify - this would produce orphans in version model"
192
+ end
190
193
  self.version_association_options = {
191
194
  :class_name => "#{self.to_s}::#{versioned_class_name}",
192
195
  :foreign_key => versioned_foreign_key
@@ -205,12 +208,12 @@ module ActiveRecord #:nodoc:
205
208
  has_many :versions, version_association_options do
206
209
  # finds earliest version of this record
207
210
  def earliest
208
- @earliest ||= find(:first, :order => '#{version_column}')
211
+ @earliest ||= order('#{version_column}').first
209
212
  end
210
213
 
211
214
  # find latest version of this record
212
215
  def latest
213
- @latest ||= find(:first, :order => '#{version_column} desc')
216
+ @latest ||= order('#{version_column} desc').first
214
217
  end
215
218
  end
216
219
  before_save :set_new_version
@@ -231,15 +234,14 @@ module ActiveRecord #:nodoc:
231
234
  const_set(versioned_class_name, Class.new(ActiveRecord::Base)).class_eval do
232
235
  def self.reloadable? ; false ; end
233
236
  # find first version before the given version
237
+ # TODO: replace "version" in selects with version_column, use select-method instead of find
234
238
  def self.before(version)
235
- find :first, :order => 'version desc',
236
- :conditions => ["#{original_class.versioned_foreign_key} = ? and version < ?", version.send(original_class.versioned_foreign_key), version.version]
239
+ where("#{original_class.versioned_foreign_key} = ? and version < ?", version.send(original_class.versioned_foreign_key), version.version).order('version desc').first
237
240
  end
238
241
 
239
242
  # find first version after the given version.
240
243
  def self.after(version)
241
- find :first, :order => 'version',
242
- :conditions => ["#{original_class.versioned_foreign_key} = ? and version > ?", version.send(original_class.versioned_foreign_key), version.version]
244
+ where("#{original_class.versioned_foreign_key} = ? and version > ?", version.send(original_class.versioned_foreign_key), version.version).order('version').first
243
245
  end
244
246
 
245
247
  def previous
@@ -263,7 +265,7 @@ module ActiveRecord #:nodoc:
263
265
  version_hash = self.attributes
264
266
  version_hash.delete "id"
265
267
  version_hash.delete self.original_class.deleted_in_original_table_flag.to_s
266
- version_hash.delete self.original_class.record_restored_flag.to_s
268
+ version_hash.delete self.original_class.record_restored_column.to_s
267
269
  version_hash.delete self.original_class.versioned_foreign_key.to_s
268
270
 
269
271
  restored_record = self.original_class.new(version_hash)
@@ -271,18 +273,26 @@ module ActiveRecord #:nodoc:
271
273
  if restored_record.respond_to? :updated_at=
272
274
  restored_record.updated_at = Time.now
273
275
  end
276
+ # DON'T EVEN THINK ABOUT CALCULATING THE VERSION NUMBER USING THE VERSIONS ASSOCIATION HERE:
277
+ # There is a problem in ActiveRecord. An association Relation will be converted to an Array internally, when the SQL-select is
278
+ # executed.
279
+ # Some ActiveRecord-Methods (for example #ActiveRecord::Base::AutosaveAssociation#save_collection_association) try to use ActiveRecord methods
280
+ # with these Relations, and if these Relations have been converted to Arrays, these calls fail with an Exception
281
+ new_version_number = self.class.where(self.original_class.versioned_foreign_key => id).order('id desc').first.send(restored_record.version_column).to_i + 1
282
+ restored_record.send("#{restored_record.version_column}=", new_version_number)
274
283
  unless restored_record.save_without_revision(perform_validation)
275
284
  raise RuntimeError.new("Couldn't restore the record, id = #{id} class = #{self.class.name}")
276
285
  end
286
+ restored_record.save_version(true, false, self.send(self.original_class.version_column))
287
+ end
277
288
 
278
- new_version = clone
279
- # new_version.version += 1
280
- new_version.send("#{self.original_class.deleted_in_original_table_flag}=", false)
281
- new_version.send("#{self.original_class.record_restored_flag}=", true)
282
- if new_version.respond_to? :updated_at=
283
- new_version.updated_at = Time.now
284
- end
285
- new_version.save!
289
+ def record_restored?
290
+ self.read_attribute(self.original_class.record_restored_column) != nil
291
+ end
292
+ alias :record_restored :record_restored?
293
+
294
+ def record_restored_from_version
295
+ self.read_attribute(self.original_class.record_restored_column)
286
296
  end
287
297
 
288
298
  def original_record_exists?
@@ -307,15 +317,15 @@ module ActiveRecord #:nodoc:
307
317
  end
308
318
 
309
319
  # Saves a version of the model in the versioned table. This is called in the after_save callback by default
310
- def save_version
311
- if @saving_version
320
+ def save_version(save_this=false, deleted_flag=false, restored_from_version=nil)
321
+ if @saving_version || save_this
312
322
  @saving_version = nil
313
323
  rev = self.class.versioned_class.new
314
324
  clone_versioned_model(self, rev)
315
325
  rev.send("#{self.class.version_column}=", send(self.class.version_column))
316
326
  rev.send("#{self.class.versioned_foreign_key}=", id)
317
- rev.send("#{self.class.deleted_in_original_table_flag}=", false)
318
- rev.send("#{self.class.record_restored_flag}=", false)
327
+ rev.send("#{self.class.deleted_in_original_table_flag}=", deleted_flag)
328
+ rev.send("#{self.class.record_restored_column}=", restored_from_version)
319
329
  if rev.respond_to? :updated_at=
320
330
  rev.updated_at = Time.now
321
331
  end
@@ -331,7 +341,7 @@ module ActiveRecord #:nodoc:
331
341
  rev.send("#{self.class.version_column}=", highest_version+1)
332
342
  rev.send("#{self.class.versioned_foreign_key}=", id)
333
343
  rev.send("#{self.class.deleted_in_original_table_flag}=", true)
334
- rev.send("#{self.class.record_restored_flag}=", false)
344
+ rev.send("#{self.class.record_restored_column}=", nil)
335
345
  if rev.respond_to? :updated_at=
336
346
  rev.updated_at = Time.now
337
347
  end
@@ -351,9 +361,12 @@ module ActiveRecord #:nodoc:
351
361
  # Reverts a model to a given version. Takes either a version number or an instance of the versioned model
352
362
  def revert_to(version)
353
363
  if version.is_a?(self.class.versioned_class)
364
+ @reverted_from = version.send(self.class.version_column)
354
365
  return false unless version.send(self.class.versioned_foreign_key) == id and !version.new_record?
355
366
  else
356
- return false unless version = versions.send("find_by_#{self.class.version_column}", version)
367
+ @reverted_from = version
368
+ version = versions.where(self.class.version_column => version).first
369
+ return false unless version
357
370
  end
358
371
  self.clone_versioned_model(version, self)
359
372
  send("#{self.class.version_column}=", version.send(self.class.version_column))
@@ -363,7 +376,13 @@ module ActiveRecord #:nodoc:
363
376
  # Reverts a model to a given version and saves the model.
364
377
  # Takes either a version number or an instance of the versioned model
365
378
  def revert_to!(version)
366
- revert_to(version) ? save_without_revision : false
379
+ if revert_to(version)
380
+ set_new_version
381
+ save_without_revision
382
+ save_version(true, false, @reverted_from)
383
+ else
384
+ false
385
+ end
367
386
  end
368
387
 
369
388
  # Temporarily turns off Optimistic Locking while saving. Used when reverting so that a new version is not created.
@@ -451,7 +470,7 @@ module ActiveRecord #:nodoc:
451
470
 
452
471
  options = args.extract_options!
453
472
  version_condition = "#{self.class.versioned_foreign_key} = #{self.id}"
454
- if options[:conditions] then
473
+ if options[:conditions]
455
474
  options[:conditions] += " and #{version_condition}"
456
475
  else
457
476
  options[:conditions] = version_condition
@@ -466,7 +485,7 @@ module ActiveRecord #:nodoc:
466
485
  def find_newest_version
467
486
  return nil if self.id.nil?
468
487
 
469
- self.class.versioned_class.find(:first, :conditions => "#{self.class.versioned_foreign_key} = #{self.id}", :order => "version DESC")
488
+ self.class.versioned_class.where("#{self.class.versioned_foreign_key} = #{self.id}").order("version DESC").first
470
489
  end
471
490
 
472
491
  def highest_version
@@ -481,22 +500,22 @@ module ActiveRecord #:nodoc:
481
500
  def find_version(version)
482
501
  return nil if self.id.nil?
483
502
 
484
- ret = self.class.versioned_class.find(:first, :conditions => "#{self.class.versioned_foreign_key} = #{self.id} and version=#{version}") # TODO: version column
503
+ ret = self.class.versioned_class.where("#{self.class.versioned_foreign_key} = #{self.id} and #{self.class.version_column}=#{version}").first
485
504
  raise "find_version: version #{version} not found in database" unless ret
486
505
  ret
487
506
  end
488
507
 
489
508
  protected
490
- # sets the new version before saving, unless you're using optimistic locking. In that case, let it take care of the version.
491
- def set_new_version
492
- @saving_version = new_record? || save_version?
493
- self.send("#{self.class.version_column}=", next_version) if new_record? || (!locking_enabled? && save_version?)
494
- end
509
+ # sets the new version before saving
510
+ def set_new_version
511
+ @saving_version = new_record? || save_version?
512
+ self.send("#{self.class.version_column}=", next_version) if new_record? || save_version?
513
+ end
495
514
 
496
- # Gets the next available version for the current record, or 1 for a new record
497
- def next_version
498
- (new_record? ? 0 : versions.calculate(:maximum, version_column).to_i) + 1
499
- end
515
+ # Gets the next available version for the current record, or 1 for a new record
516
+ def next_version
517
+ (new_record? ? 0 : versions.calculate(:maximum, version_column).to_i) + 1
518
+ end
500
519
 
501
520
  module ClassMethods
502
521
  # Returns an array of columns that are versioned. See non_versioned_columns
@@ -523,13 +542,13 @@ module ActiveRecord #:nodoc:
523
542
  t.column versioned_foreign_key, :integer
524
543
  t.column version_column, :integer
525
544
  t.column deleted_in_original_table_flag, :boolean, :default => false
526
- t.column record_restored_flag, :boolean, :default => false
545
+ t.column record_restored_column, :integer, :default => nil
527
546
  end
528
547
 
529
548
  self.versioned_columns.each do |col|
530
549
  self.connection.add_column versioned_table_name, col.name, col.type,
531
550
  :limit => col.limit,
532
- :default => col.default,
551
+ :default => col.cast_type.type_cast_from_database(col.default), # convert strings to ruby types
533
552
  :scale => col.scale,
534
553
  :precision => col.precision
535
554
  end
@@ -537,7 +556,7 @@ module ActiveRecord #:nodoc:
537
556
  if type_col = self.columns_hash[inheritance_column]
538
557
  self.connection.add_column versioned_table_name, versioned_inheritance_column, type_col.type,
539
558
  :limit => type_col.limit,
540
- :default => type_col.default,
559
+ :default => type_col.cast_type.type_cast_from_database(type_col.default), # convert strings to ruby types
541
560
  :scale => type_col.scale,
542
561
  :precision => type_col.precision
543
562
  end
@@ -551,12 +570,12 @@ module ActiveRecord #:nodoc:
551
570
  end
552
571
 
553
572
  def restore_deleted(id)
554
- version_record = versioned_class.find(:first, :conditions => "#{versioned_foreign_key} = #{id}", :order => "version DESC")
573
+ version_record = versioned_class.where("#{versioned_foreign_key} = #{id}").order("version DESC").first
555
574
  version_record.restore
556
575
  end
557
576
 
558
577
  def restore_deleted_version(id, version)
559
- version_record = versioned_class.find(:first, :conditions => "#{versioned_foreign_key} = #{id} and version = #{version}")
578
+ version_record = versioned_class.where("#{versioned_foreign_key} = #{id} and version = #{version}").first
560
579
  version_record.restore
561
580
  end
562
581
 
@@ -604,7 +623,6 @@ module ActiveRecord #:nodoc:
604
623
  end
605
624
 
606
625
  # TISS extension: do not pull this.
607
- # TODO: Move to TISS app (initializer)
608
626
  module ActiveRecord #:nodoc:
609
627
  module ConnectionAdapters #:nodoc:
610
628
  class TableDefinition
@@ -12,8 +12,8 @@ Gem::Specification.new do |s|
12
12
  ## If your rubyforge_project name is different, then edit it and comment out
13
13
  ## the sub! line in the Rakefile
14
14
  s.name = 'rtiss_acts_as_versioned'
15
- s.version = '0.8.2'
16
- s.date = '2014-11-18'
15
+ s.version = '0.8.3'
16
+ s.date = '2016-01-25'
17
17
  s.rubyforge_project = 'rtiss_acts_as_versioned'
18
18
  s.summary = "Add simple versioning to ActiveRecord models (TISS version)."
19
19
  s.description = "Add simple versioning to ActiveRecord models (TISS version).
@@ -31,10 +31,11 @@ to use technoweenie's version (can be found also on github)"
31
31
  s.rdoc_options = ["--charset=UTF-8"]
32
32
  s.extra_rdoc_files = %w[README MIT-LICENSE CHANGELOG]
33
33
 
34
- s.add_dependency 'activerecord', ">= 3.0.9"
34
+ s.add_dependency 'activerecord', ">= 4.2.5"
35
35
  s.add_development_dependency 'sqlite3-ruby', "~> 1.3.1"
36
- s.add_development_dependency 'rails', "~> 3.0.20"
37
- s.add_development_dependency 'mysql', "~> 2.8.1"
36
+ s.add_development_dependency 'rails', "~> 4.2.5"
37
+ s.add_development_dependency 'activerecord-testcase'
38
+ s.add_development_dependency 'activerecord-deprecated_finders' # todo alte, hash-basierte finders auf die neue AR Query-API migrieren
38
39
 
39
40
  ## Leave this section as-is. It will be automatically generated from the
40
41
  ## contents of your Git repository via the gemspec task. DO NOT REMOVE
@@ -59,7 +60,7 @@ to use technoweenie's version (can be found also on github)"
59
60
  test/fixtures/locked_pages.yml
60
61
  test/fixtures/locked_pages_revisions.yml
61
62
  test/fixtures/locked_rolle.rb
62
- test/fixtures/migrations/1_add_versioned_tables.rb
63
+ test/fixtures/migrations/2_add_versioned_tables.rb
63
64
  test/fixtures/page.rb
64
65
  test/fixtures/pages.yml
65
66
  test/fixtures/pages_h.yml
@@ -1,22 +1,17 @@
1
- require "rubygems"
2
1
  require "bundler"
3
2
  Bundler.setup(:default, :development)
4
3
 
5
4
  $:.unshift(File.dirname(__FILE__) + '/../lib')
6
- require 'test/unit'
5
+ require 'minitest/autorun'
7
6
  require 'active_support'
8
7
  require 'active_record'
9
8
  require 'active_record/fixtures'
10
9
  require 'active_record/test_case'
11
-
12
- begin
13
- require 'ruby-debug'
14
- Debugger.start
15
- rescue LoadError
16
- end
17
-
10
+ require 'active_record/deprecated_finders'
18
11
  require 'rtiss_acts_as_versioned'
19
12
 
13
+ ActiveSupport::TestCase.test_order = :sorted
14
+
20
15
  config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
21
16
  ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
22
17
  ActiveRecord::Base.configurations = {'test' => config[ENV['DB'] || 'sqlite3']}
@@ -1,10 +1,12 @@
1
1
  welcome:
2
2
  id: 1
3
3
  title: Welcome to the weblog
4
- lock_version: 24
4
+ version: 24
5
+ lock_version: 1
5
6
  type: LockedPage
6
7
  thinking:
7
8
  id: 2
8
9
  title: So I was thinking
9
- lock_version: 24
10
+ version: 24
11
+ lock_version: 1
10
12
  type: SpecialLockedPage
@@ -2,26 +2,26 @@ welcome_1:
2
2
  id: 1
3
3
  page_id: 1
4
4
  title: Welcome to the weblg
5
- lock_version: 23
5
+ version: 23
6
6
  version_type: LockedPage
7
7
 
8
8
  welcome_2:
9
9
  id: 2
10
10
  page_id: 1
11
11
  title: Welcome to the weblog
12
- lock_version: 24
12
+ version: 24
13
13
  version_type: LockedPage
14
14
 
15
15
  thinking_1:
16
16
  id: 3
17
17
  page_id: 2
18
18
  title: So I was thinking!!!
19
- lock_version: 23
19
+ version: 23
20
20
  version_type: SpecialLockedPage
21
21
 
22
22
  thinking_2:
23
23
  id: 4
24
24
  page_id: 2
25
25
  title: So I was thinking
26
- lock_version: 24
26
+ version: 24
27
27
  version_type: SpecialLockedPage
@@ -1,6 +1,6 @@
1
1
  # Same as Rolle except for the presence of the lock_version field
2
2
  class LockedRolle < ActiveRecord::Base
3
- set_table_name 'locked_rolle'
3
+ self.table_name = 'locked_rolle'
4
4
  acts_as_versioned
5
5
 
6
6
  validates_presence_of :name
@@ -1,6 +1,6 @@
1
1
  class AddVersionedTables < ActiveRecord::Migration
2
2
  def self.up
3
- create_table("things") do |t|
3
+ create_table "things" do |t|
4
4
  t.column :title, :text
5
5
  t.column :price, :decimal, :precision => 7, :scale => 2
6
6
  t.column :type, :string
@@ -1,8 +1,9 @@
1
1
  class Page < ActiveRecord::Base
2
2
  belongs_to :author
3
- has_many :authors, :through => :versions, :order => 'name'
3
+ has_many :authors, -> { order(:name)}, :through => :versions
4
4
  belongs_to :revisor, :class_name => 'Author'
5
- has_many :revisors, :class_name => 'Author', :through => :versions, :order => 'name'
5
+ has_many :revisors, -> { order(:name)}, :class_name => 'Author', :through => :versions
6
+
6
7
  acts_as_versioned :if => :feeling_good? do
7
8
  def self.included(base)
8
9
  base.cattr_accessor :feeling_good
@@ -29,7 +30,6 @@ class LockedPage < ActiveRecord::Base
29
30
  :foreign_key => :page_id,
30
31
  :table_name => :locked_pages_revisions,
31
32
  :class_name => 'LockedPageRevision',
32
- :version_column => :lock_version,
33
33
  :limit => 2,
34
34
  :if_changed => :title,
35
35
  :extend => LockedPageExtension
@@ -1,5 +1,5 @@
1
1
  class Rolle < ActiveRecord::Base
2
- set_table_name 'rolle'
2
+ self.table_name = 'rolle'
3
3
  acts_as_versioned
4
4
 
5
5
  validates_presence_of :name
@@ -1,6 +1,6 @@
1
1
  class Widget < ActiveRecord::Base
2
2
  acts_as_versioned :sequence_name => 'widgets_seq', :association_options => {
3
- :dependent => :nullify, :order => 'version desc'
3
+ :order => 'version desc' # Don't nullify the foreign key column when deleting the original record! :dependent => :nullify option removed
4
4
  }
5
5
  non_versioned_columns << 'foo'
6
6
  end
@@ -8,39 +8,22 @@ if ActiveRecord::Base.connection.supports_migrations?
8
8
 
9
9
  class MigrationTest < ActiveSupport::TestCase
10
10
  self.use_transactional_fixtures = false
11
- def teardown
12
- if ActiveRecord::Base.connection.respond_to?(:initialize_schema_information)
13
- ActiveRecord::Base.connection.initialize_schema_information
14
- ActiveRecord::Base.connection.update "UPDATE schema_info SET version = 0"
15
- else
16
- ActiveRecord::Base.connection.initialize_schema_migrations_table
17
- ActiveRecord::Base.connection.assume_migrated_upto_version(0)
18
- end
19
-
20
- Thing.connection.drop_table "things" rescue nil
21
- Thing.connection.drop_table "thing_versions" rescue nil
22
- Thing.reset_column_information
23
- end
24
-
11
+
25
12
  def test_versioned_migration
26
- assert_raises(ActiveRecord::StatementInvalid) { Thing.create :title => 'blah blah' }
27
13
  # take 'er up
28
- ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/')
14
+ migrations_path = File.expand_path(File.dirname(__FILE__)) + '/fixtures/migrations'
15
+ require migrations_path + '/2_add_versioned_tables'
16
+ ActiveRecord::Migrator.new(:up, ActiveRecord::Migrator.migrations(migrations_path), 2).run
29
17
  t = Thing.create :title => 'blah blah', :price => 123.45, :type => 'Thing'
30
18
  assert_equal 1, t.versions.size
31
19
 
32
20
  # check that the price column has remembered its value correctly
33
21
  assert_equal t.price, t.versions.first.price
34
22
  assert_equal t.title, t.versions.first.title
35
- assert_equal t[:type], t.versions.first[:type]
36
-
23
+
37
24
  # make sure that the precision of the price column has been preserved
38
25
  assert_equal 7, Thing::Version.columns.find{|c| c.name == "price"}.precision
39
26
  assert_equal 2, Thing::Version.columns.find{|c| c.name == "price"}.scale
40
-
41
- # now lets take 'er back down
42
- ActiveRecord::Migrator.down(File.dirname(__FILE__) + '/fixtures/migrations/')
43
- assert_raises(ActiveRecord::StatementInvalid) { Thing.create :title => 'blah blah' }
44
27
  end
45
28
  end
46
29
  end
data/test/schema.rb CHANGED
@@ -1,4 +1,4 @@
1
- ActiveRecord::Schema.define(:version => 0) do
1
+ ActiveRecord::Schema.define(:version => 1) do
2
2
  create_table :pages, :force => true do |t|
3
3
  t.column :version, :integer
4
4
  t.column :title, :string, :limit => 255
@@ -19,7 +19,7 @@ ActiveRecord::Schema.define(:version => 0) do
19
19
  t.column :author_id, :integer
20
20
  t.column :revisor_id, :integer
21
21
  t.column :deleted_in_original_table, :boolean
22
- t.column :record_restored, :boolean
22
+ t.column :record_restored, :integer, :precision => 38, :scale => 0, :default => nil
23
23
  end
24
24
 
25
25
  add_index :pages_h, [:page_id, :version], :unique => true
@@ -31,6 +31,7 @@ ActiveRecord::Schema.define(:version => 0) do
31
31
 
32
32
  create_table :locked_pages, :force => true do |t|
33
33
  t.column :lock_version, :integer
34
+ t.column :version, :integer
34
35
  t.column :title, :string, :limit => 255
35
36
  t.column :body, :text
36
37
  t.column :type, :string, :limit => 255
@@ -38,16 +39,17 @@ ActiveRecord::Schema.define(:version => 0) do
38
39
 
39
40
  create_table :locked_pages_revisions, :force => true do |t|
40
41
  t.column :page_id, :integer
41
- t.column :lock_version, :integer
42
+ t.column :version, :integer
43
+ #t.column :lock_version, :integer
42
44
  t.column :title, :string, :limit => 255
43
45
  t.column :body, :text
44
46
  t.column :version_type, :string, :limit => 255
45
47
  t.column :updated_at, :datetime
46
48
  t.column :deleted_in_original_table, :boolean
47
- t.column :record_restored, :boolean
49
+ t.column :record_restored, :integer, :precision => 38, :scale => 0, :default => nil
48
50
  end
49
51
 
50
- add_index :locked_pages_revisions, [:page_id, :lock_version], :unique => true
52
+ add_index :locked_pages_revisions, [:page_id, :version], :unique => true
51
53
 
52
54
  create_table :widgets, :force => true do |t|
53
55
  t.column :name, :string, :limit => 50
@@ -62,7 +64,7 @@ ActiveRecord::Schema.define(:version => 0) do
62
64
  t.column :version, :integer
63
65
  t.column :updated_at, :datetime
64
66
  t.column :deleted_in_original_table, :boolean
65
- t.column :record_restored, :boolean
67
+ t.column :record_restored, :integer, :precision => 38, :scale => 0, :default => nil
66
68
  end
67
69
 
68
70
  add_index :widgets_h, [:widget_id, :version], :unique => true
@@ -83,7 +85,7 @@ ActiveRecord::Schema.define(:version => 0) do
83
85
  t.column :doesnt_trigger_version,:string
84
86
  t.column :version, :integer
85
87
  t.column :deleted_in_original_table, :boolean
86
- t.column :record_restored, :boolean
88
+ t.column :record_restored, :integer, :precision => 38, :scale => 0, :default => nil
87
89
  end
88
90
 
89
91
  add_index :landmark_h, [:landmark_id, :version], :unique => true
@@ -111,7 +113,7 @@ ActiveRecord::Schema.define(:version => 0) do
111
113
  t.string "name", :limit => 50
112
114
  t.string "beschreibung", :limit => 250
113
115
  t.boolean "deleted_in_original_table", :precision => 1, :scale => 0
114
- t.boolean "record_restored", :precision => 1, :scale => 0
116
+ t.integer "record_restored", :precision => 38, :scale => 0, :default => nil
115
117
  t.integer "parent_id", :precision => 38, :scale => 0
116
118
  t.string "beschreibung_intern", :limit => 4000
117
119
  t.string "geltungsbereich", :limit => 1000
@@ -144,7 +146,7 @@ ActiveRecord::Schema.define(:version => 0) do
144
146
  t.string "name", :limit => 50
145
147
  t.string "beschreibung", :limit => 250
146
148
  t.boolean "deleted_in_original_table", :precision => 1, :scale => 0
147
- t.boolean "record_restored", :precision => 1, :scale => 0
149
+ t.integer "record_restored", :precision => 38, :scale => 0, :default => nil
148
150
  t.integer "parent_id", :precision => 38, :scale => 0
149
151
  t.string "beschreibung_intern", :limit => 4000
150
152
  t.string "geltungsbereich", :limit => 1000
data/test/tiss_test.rb CHANGED
@@ -45,7 +45,7 @@ class TissTest < ActiveSupport::TestCase
45
45
 
46
46
  def test_deleted_in_original_table
47
47
  record = create_object('test deleted_in_orginal_table')
48
- version_record = record.versions.find(:first)
48
+ version_record = record.versions.first
49
49
  assert version_record != nil
50
50
 
51
51
  assert !version_record.deleted_in_original_table
@@ -106,23 +106,63 @@ class TissTest < ActiveSupport::TestCase
106
106
  oid = o.id
107
107
  v = o.find_version(1)
108
108
  assert v!=nil
109
-
109
+
110
110
  assert_raises(RuntimeError) { v.restore }
111
111
  assert !v.deleted_in_original_table
112
112
  assert !v.record_restored, "Record_restored shows that the record was undeleted (should be false) for a newly created record"
113
113
 
114
+ old_version = o.version
114
115
  o.destroy
115
116
  v = o.find_newest_version
116
- assert v.deleted_in_original_table
117
+ first_delete_version = v.version
118
+ assert v.deleted_in_original_table, "Deleted-Flag in versioned record is not set"
119
+ assert_equal old_version + 1, v.version, "Destroy did not increment version number in history record"
117
120
 
118
121
  v.restore
122
+ restored_version = v.version
119
123
  assert !v.record_restored, "Record_restored shows that the record was undeleted (should be false) for the restored version record (but should be in the newly created record)"
120
124
  o = Rolle.find oid
121
- assert v.version == o.version, "Version field not restored correctly"
122
-
123
125
  v = o.find_newest_version
126
+ v_old = v
127
+ assert_equal v.version, o.version
128
+ assert_equal old_version + 2, v.version, "Version field not restored correctly"
124
129
  assert !v.deleted_in_original_table, "Deleted_in_original_table doesn't show that the record was undeleted (should be false)"
125
130
  assert v.record_restored, "Record_restored doesn't show that the record was undeleted (should be true) for the version record created upon restore"
131
+ assert_equal restored_version, v.record_restored_from_version
132
+
133
+ o.name = 'kaputt'
134
+ assert o.save
135
+ o.destroy
136
+ v = o.find_newest_version
137
+ v.restore
138
+ o = Rolle.find oid
139
+ assert_equal v.version + 1, o.version
140
+ assert_equal 'kaputt', o.name
141
+ assert_equal v.version, o.find_newest_version.record_restored_from_version
142
+ o.destroy
143
+ v_old.restore
144
+ o = Rolle.find oid
145
+ assert_equal 'lebt', o.name
146
+ assert_equal v_old.version, o.find_newest_version.record_restored_from_version
147
+ end
148
+
149
+ def test_restore_and_destroy_with_revision_on_every_change
150
+ r = Rolle.new(:name => 'karin')
151
+ assert r.save
152
+ r.name = 'zak'
153
+ assert r.save
154
+ assert_equal 2, Rolle::Version.count
155
+ r.destroy
156
+ assert_equal 0, Rolle.count
157
+ assert_equal 3, Rolle::Version.count
158
+ assert version = r.find_version(3)
159
+ assert version.deleted_in_original_table?
160
+ assert version = r.find_version(2)
161
+ version.restore
162
+ assert r = Rolle.first
163
+ assert r.find_newest_version.record_restored?
164
+ assert_equal 4, Rolle::Version.count
165
+ assert_equal 4, r.version
126
166
  end
127
167
 
128
168
  def test_original_record_exists
@@ -193,7 +233,8 @@ class TissTest < ActiveSupport::TestCase
193
233
  assert r.save
194
234
  r.name = 'zak'
195
235
  assert r.save
196
- assert_equal 2, r.versions.size
236
+ r.reload
237
+ assert_equal 2, r.versions.size
197
238
  assert_equal 2, r.versions.count
198
239
  end
199
240
 
@@ -205,9 +246,9 @@ class TissTest < ActiveSupport::TestCase
205
246
 
206
247
  r = Rolle.new(:name => 'karin')
207
248
  assert r.save
208
-
209
249
  assert_raises RuntimeError do version.restore end
210
- assert_nothing_raised do version.restore(perform_validations = false) end
250
+ #assert_nothing_raised do
251
+ version.restore(perform_validations = false) #end
211
252
  end
212
253
 
213
254
  def test_save_without_revision
@@ -1,5 +1,6 @@
1
1
  require File.join(File.dirname(__FILE__), 'abstract_unit')
2
2
  require File.join(File.dirname(__FILE__), 'fixtures/page')
3
+ require File.join(File.dirname(__FILE__), 'fixtures/landmark')
3
4
  require File.join(File.dirname(__FILE__), 'fixtures/widget')
4
5
 
5
6
  class VersionedTest < ActiveSupport::TestCase
@@ -29,11 +30,14 @@ class VersionedTest < ActiveSupport::TestCase
29
30
 
30
31
  def test_rollback_with_version_number
31
32
  p = pages(:welcome)
33
+ versioncount = p.versions.count
32
34
  assert_equal 24, p.version
33
35
  assert_equal 'Welcome to the weblog', p.title
34
36
 
35
37
  assert p.revert_to!(23), "Couldn't revert to 23"
36
- assert_equal 23, p.version
38
+ assert p.reload
39
+ assert_equal versioncount + 1, p.versions.count
40
+ assert_equal 25, p.version
37
41
  assert_equal 'Welcome to the weblg', p.title
38
42
  end
39
43
 
@@ -56,11 +60,14 @@ class VersionedTest < ActiveSupport::TestCase
56
60
 
57
61
  def test_rollback_with_version_class
58
62
  p = pages(:welcome)
63
+ versioncount = p.versions.count
59
64
  assert_equal 24, p.version
60
65
  assert_equal 'Welcome to the weblog', p.title
61
66
 
62
67
  assert p.revert_to!(p.versions.find_by_version(23)), "Couldn't revert to 23"
63
- assert_equal 23, p.version
68
+ assert p.reload
69
+ assert_equal versioncount + 1, p.versions.count
70
+ assert_equal 25, p.version
64
71
  assert_equal 'Welcome to the weblg', p.title
65
72
  end
66
73
 
@@ -81,7 +88,7 @@ class VersionedTest < ActiveSupport::TestCase
81
88
  assert_equal 'Welcome to the weblog', p.title
82
89
  assert_equal 'LockedPage', p.versions.first.version_type
83
90
 
84
- assert p.revert_to!(p.versions.first.lock_version), "Couldn't revert to 23"
91
+ assert p.revert_to!(p.versions.first.version), "Couldn't revert to 23"
85
92
  assert_equal 'Welcome to the weblg', p.title
86
93
  assert_equal 'LockedPage', p.versions.first.version_type
87
94
  end
@@ -108,7 +115,7 @@ class VersionedTest < ActiveSupport::TestCase
108
115
  p = locked_pages(:thinking)
109
116
  assert_equal 'So I was thinking', p.title
110
117
 
111
- assert p.revert_to!(p.versions.first.lock_version), "Couldn't revert to 1"
118
+ assert p.revert_to!(p.versions.first.version), "Couldn't revert to 1"
112
119
  assert_equal 'So I was thinking!!!', p.title
113
120
  assert_equal 'SpecialLockedPage', p.versions.first.version_type
114
121
  end
@@ -202,7 +209,7 @@ class VersionedTest < ActiveSupport::TestCase
202
209
  p.title = "title#{i}"
203
210
  p.save
204
211
  assert_equal "title#{i}", p.title
205
- assert_equal (i+4), p.lock_version
212
+ assert_equal (i+4), p.version
206
213
  assert p.versions(true).size <= 2, "locked version can only store 2 versions"
207
214
  end
208
215
  end
@@ -215,25 +222,25 @@ class VersionedTest < ActiveSupport::TestCase
215
222
 
216
223
  def test_track_altered_attributes
217
224
  p = LockedPage.create! :title => "title"
218
- assert_equal 1, p.lock_version
225
+ assert_equal 1, p.version
219
226
  assert_equal 1, p.versions(true).size
220
227
 
221
228
  p.body = 'whoa'
222
229
  assert !p.save_version?
223
230
  p.save
224
- assert_equal 2, p.lock_version # still increments version because of optimistic locking
231
+ assert_equal 1, p.version # no increment, because we're not using lock_version column
225
232
  assert_equal 1, p.versions(true).size
226
233
 
227
234
  p.title = 'updated title'
228
235
  assert p.save_version?
229
236
  p.save
230
- assert_equal 3, p.lock_version
231
- assert_equal 1, p.versions(true).size # version 1 deleted
237
+ assert_equal 2, p.version
238
+ assert_equal 2, p.versions(true).size
232
239
 
233
240
  p.title = 'updated title!'
234
241
  assert p.save_version?
235
242
  p.save
236
- assert_equal 4, p.lock_version
243
+ assert_equal 3, p.version
237
244
  assert_equal 2, p.versions(true).size # version 1 deleted
238
245
  end
239
246
 
@@ -273,8 +280,7 @@ class VersionedTest < ActiveSupport::TestCase
273
280
 
274
281
  association = Widget.reflect_on_association(:versions)
275
282
  options = association.options
276
- assert_equal :nullify, options[:dependent]
277
- assert_equal 'version desc', options[:order]
283
+ #assert_equal :nullify, options[:dependent] #Removed! we do not nullify the foreign key, because on restore we want to set the correct original ID
278
284
  assert_equal 'widget_id', options[:foreign_key]
279
285
 
280
286
  widget = Widget.create! :name => 'new widget'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rtiss_acts_as_versioned
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.2
4
+ version: 0.8.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rick Olson
@@ -10,64 +10,78 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2014-11-18 00:00:00.000000000 Z
13
+ date: 2016-01-25 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
17
17
  requirement: !ruby/object:Gem::Requirement
18
18
  requirements:
19
- - - '>='
19
+ - - ">="
20
20
  - !ruby/object:Gem::Version
21
- version: 3.0.9
21
+ version: 4.2.5
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
- - - '>='
26
+ - - ">="
27
27
  - !ruby/object:Gem::Version
28
- version: 3.0.9
28
+ version: 4.2.5
29
29
  - !ruby/object:Gem::Dependency
30
30
  name: sqlite3-ruby
31
31
  requirement: !ruby/object:Gem::Requirement
32
32
  requirements:
33
- - - ~>
33
+ - - "~>"
34
34
  - !ruby/object:Gem::Version
35
35
  version: 1.3.1
36
36
  type: :development
37
37
  prerelease: false
38
38
  version_requirements: !ruby/object:Gem::Requirement
39
39
  requirements:
40
- - - ~>
40
+ - - "~>"
41
41
  - !ruby/object:Gem::Version
42
42
  version: 1.3.1
43
43
  - !ruby/object:Gem::Dependency
44
44
  name: rails
45
45
  requirement: !ruby/object:Gem::Requirement
46
46
  requirements:
47
- - - ~>
47
+ - - "~>"
48
48
  - !ruby/object:Gem::Version
49
- version: 3.0.20
49
+ version: 4.2.5
50
50
  type: :development
51
51
  prerelease: false
52
52
  version_requirements: !ruby/object:Gem::Requirement
53
53
  requirements:
54
- - - ~>
54
+ - - "~>"
55
55
  - !ruby/object:Gem::Version
56
- version: 3.0.20
56
+ version: 4.2.5
57
57
  - !ruby/object:Gem::Dependency
58
- name: mysql
58
+ name: activerecord-testcase
59
59
  requirement: !ruby/object:Gem::Requirement
60
60
  requirements:
61
- - - ~>
61
+ - - ">="
62
62
  - !ruby/object:Gem::Version
63
- version: 2.8.1
63
+ version: '0'
64
64
  type: :development
65
65
  prerelease: false
66
66
  version_requirements: !ruby/object:Gem::Requirement
67
67
  requirements:
68
- - - ~>
68
+ - - ">="
69
69
  - !ruby/object:Gem::Version
70
- version: 2.8.1
70
+ version: '0'
71
+ - !ruby/object:Gem::Dependency
72
+ name: activerecord-deprecated_finders
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
71
85
  description: "Add simple versioning to ActiveRecord models (TISS version).\n\nEach
72
86
  model has a to-many model named mymodel_h which records all changes \n(including
73
87
  destroys but not deletes) made to the model. This is the version\nused by http://tiss.tuwien.ac.at
@@ -100,7 +114,7 @@ files:
100
114
  - test/fixtures/locked_pages.yml
101
115
  - test/fixtures/locked_pages_revisions.yml
102
116
  - test/fixtures/locked_rolle.rb
103
- - test/fixtures/migrations/1_add_versioned_tables.rb
117
+ - test/fixtures/migrations/2_add_versioned_tables.rb
104
118
  - test/fixtures/page.rb
105
119
  - test/fixtures/pages.yml
106
120
  - test/fixtures/pages_h.yml
@@ -115,17 +129,17 @@ licenses: []
115
129
  metadata: {}
116
130
  post_install_message:
117
131
  rdoc_options:
118
- - --charset=UTF-8
132
+ - "--charset=UTF-8"
119
133
  require_paths:
120
134
  - lib
121
135
  required_ruby_version: !ruby/object:Gem::Requirement
122
136
  requirements:
123
- - - '>='
137
+ - - ">="
124
138
  - !ruby/object:Gem::Version
125
139
  version: '0'
126
140
  required_rubygems_version: !ruby/object:Gem::Requirement
127
141
  requirements:
128
- - - '>='
142
+ - - ">="
129
143
  - !ruby/object:Gem::Version
130
144
  version: '0'
131
145
  requirements: []
@@ -135,3 +149,4 @@ signing_key:
135
149
  specification_version: 4
136
150
  summary: Add simple versioning to ActiveRecord models (TISS version).
137
151
  test_files: []
152
+ has_rdoc: