public
Description: ActiveRecord plugin for versioning your models.
Clone URL: git://github.com/technoweenie/acts_as_versioned.git
* (16 Jun 2008) Backwards Compatibility is overrated (big updates for 
rails 2.1)

  * Remove last traces of #non_versioned_fields
  * Remove AR::Base.find_version and AR::Base.find_versions, rely on AR 
  association proxies and named_scope
  * Remove #versions_count, rely on AR association counter caching.
  * Remove #versioned_attributes, basically the same as 
  AR::Base.versioned_columns
technoweenie (author)
Mon Jun 16 23:26:42 -0700 2008
commit  36b078359dcd92295c992fff630076a634b2fda1
tree    18d410830d663e45f2a95d3fa2388ac12f5b0fbc
parent  550f5e0736a06185bf3585d8f6efa6662dc1fac2
...
1
 
 
 
 
 
 
 
 
 
2
3
4
...
 
1
2
3
4
5
6
7
8
9
10
11
12
0
@@ -1,4 +1,12 @@
0
-*SVN* (version numbers are overrated)
0
+*GIT* (version numbers are overrated)
0
+
0
+* (16 Jun 2008) Backwards Compatibility is overrated (big updates for rails 2.1)
0
+
0
+ * Use ActiveRecord 2.1's dirty attribute checking instead [Asa Calow]
0
+ * Remove last traces of #non_versioned_fields
0
+ * Remove AR::Base.find_version and AR::Base.find_versions, rely on AR association proxies and named_scope
0
+ * Remove #versions_count, rely on AR association counter caching.
0
+ * Remove #versioned_attributes, basically the same as AR::Base.versioned_columns
0
 
0
 * (5 Oct 2006) Allow customization of #versions association options [Dan Peterson]
0
 
...
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
...
280
281
282
283
284
285
286
287
288
289
290
...
293
294
295
296
 
297
298
 
299
300
301
...
305
306
307
308
309
 
310
311
312
313
314
315
316
317
318
319
320
 
321
322
323
324
325
 
326
327
328
...
347
348
349
350
351
352
353
354
355
356
357
 
358
359
360
361
362
363
 
 
364
365
366
...
413
414
415
416
 
417
418
419
420
421
422
 
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
 
450
451
452
...
470
471
472
473
474
475
 
 
 
476
477
478
479
480
481
482
483
 
 
 
484
485
486
...
177
178
179
 
 
 
 
 
 
 
 
 
180
181
182
...
271
272
273
 
 
 
 
 
274
275
276
...
279
280
281
 
282
283
 
284
285
286
287
...
291
292
293
 
 
294
295
296
297
 
 
 
 
298
299
300
 
301
302
303
304
305
 
306
307
308
309
...
328
329
330
 
 
 
 
 
331
332
 
333
334
335
336
337
 
 
338
339
340
341
342
...
389
390
391
 
392
393
394
395
396
 
 
397
398
399
400
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
401
402
 
403
404
405
406
...
424
425
426
 
 
 
427
428
429
430
431
432
433
434
 
 
 
435
436
437
438
439
440
0
@@ -177,15 +177,6 @@ module ActiveRecord #:nodoc:
0
             :version_column, :max_version_limit, :track_altered_attributes, :version_condition, :version_sequence_name, :non_versioned_columns,
0
             :version_association_options, :version_if_changed
0
 
0
- # legacy
0
- alias_method :non_versioned_fields, :non_versioned_columns
0
- alias_method :non_versioned_fields=, :non_versioned_columns=
0
-
0
- class << self
0
- alias_method :non_versioned_fields, :non_versioned_columns
0
- alias_method :non_versioned_fields=, :non_versioned_columns=
0
- end
0
-
0
           self.versioned_class_name = options[:class_name] || "Version"
0
           self.versioned_foreign_key = options[:foreign_key] || self.to_s.foreign_key
0
           self.versioned_table_name = options[:table_name] || "#{table_name_prefix}#{base_class.name.demodulize.underscore}_versions#{table_name_suffix}"
0
@@ -280,11 +271,6 @@ module ActiveRecord #:nodoc:
0
           base.extend ClassMethods
0
         end
0
 
0
- # Finds a specific version of this record
0
- def find_version(version = nil)
0
- self.class.find_version(id, version)
0
- end
0
-
0
         # Saves a version of the model if applicable
0
         def save_version
0
           save_version_on_create if save_version?
0
@@ -293,9 +279,9 @@ module ActiveRecord #:nodoc:
0
         # Saves a version of the model in the versioned table. This is called in the after_save callback by default
0
         def save_version_on_create
0
           rev = self.class.versioned_class.new
0
- self.clone_versioned_model(self, rev)
0
+ clone_versioned_model(self, rev)
0
           rev.version = send(self.class.version_column)
0
- rev.send("#{self.class.versioned_foreign_key}=", self.id)
0
+ rev.send("#{self.class.versioned_foreign_key}=", id)
0
           rev.save
0
         end
0
 
0
@@ -305,24 +291,19 @@ module ActiveRecord #:nodoc:
0
           return if self.class.max_version_limit == 0
0
           excess_baggage = send(self.class.version_column).to_i - self.class.max_version_limit
0
           if excess_baggage > 0
0
- sql = "DELETE FROM #{self.class.versioned_table_name} WHERE version <= #{excess_baggage} AND #{self.class.versioned_foreign_key} = #{self.id}"
0
- self.class.versioned_class.connection.execute sql
0
+ self.class.versioned_class.delete_all ["version <= ? and #{self.class.versioned_foreign_key} = ?", excess_baggage, id]
0
           end
0
         end
0
 
0
- def versions_count
0
- version
0
- end
0
-
0
         # Reverts a model to a given version. Takes either a version number or an instance of the versioned model
0
         def revert_to(version)
0
           if version.is_a?(self.class.versioned_class)
0
- return false unless version.send(self.class.versioned_foreign_key) == self.id and !version.new_record?
0
+ return false unless version.send(self.class.versioned_foreign_key) == id and !version.new_record?
0
           else
0
             return false unless version = versions.find_by_version(version)
0
           end
0
           self.clone_versioned_model(version, self)
0
- self.send("#{self.class.version_column}=", version.version)
0
+ send("#{self.class.version_column}=", version.version)
0
           true
0
         end
0
 
0
@@ -347,20 +328,15 @@ module ActiveRecord #:nodoc:
0
             end
0
           end
0
         end
0
-
0
- # Returns an array of attribute keys that are versioned. See non_versioned_columns
0
- def versioned_attributes
0
- self.attributes.keys.select { |k| !self.class.non_versioned_columns.include?(k) }
0
- end
0
         
0
         def altered?
0
- self.track_altered_attributes ? (self.version_if_changed.map(&:to_s) - changed).length == 0 : changed?
0
+ track_altered_attributes ? (version_if_changed.map(&:to_s) - changed).length == 0 : changed?
0
         end
0
 
0
         # Clones a model. Used when saving a new version or reverting a model's version.
0
         def clone_versioned_model(orig_model, new_model)
0
- self.versioned_attributes.each do |key|
0
- new_model.send("#{key}=", orig_model.send(key)) if orig_model.has_attribute?(key)
0
+ self.class.versioned_columns.each do |col|
0
+ new_model.send("#{col.name}=", orig_model.send(col.name)) if orig_model.has_attribute?(col.name)
0
           end
0
 
0
           if orig_model.is_a?(self.class.versioned_class)
0
@@ -413,40 +389,18 @@ module ActiveRecord #:nodoc:
0
         protected
0
           # sets the new version before saving, unless you're using optimistic locking. In that case, let it take care of the version.
0
           def set_new_version
0
- self.send("#{self.class.version_column}=", self.next_version) if new_record? || (!locking_enabled? && save_version?)
0
+ self.send("#{self.class.version_column}=", next_version) if new_record? || (!locking_enabled? && save_version?)
0
           end
0
 
0
           # Gets the next available version for the current record, or 1 for a new record
0
           def next_version
0
- return 1 if new_record?
0
- (versions.calculate(:max, :version) || 0) + 1
0
+ (new_record? ? 0 : versions.calculate(:max, :version).to_i) + 1
0
           end
0
 
0
         module ClassMethods
0
- # Finds a specific version of a specific row of this model
0
- def find_version(id, version = nil)
0
- return find(id) unless version
0
-
0
- conditions = ["#{versioned_foreign_key} = ? AND version = ?", id, version]
0
- options = { :conditions => conditions, :limit => 1 }
0
-
0
- if result = find_versions(id, options).first
0
- result
0
- else
0
- raise RecordNotFound, "Couldn't find #{name} with ID=#{id} and VERSION=#{version}"
0
- end
0
- end
0
-
0
- # Finds versions of a specific model. Takes an options hash like <tt>find</tt>
0
- def find_versions(id, options = {})
0
- versioned_class.find :all, {
0
- :conditions => ["#{versioned_foreign_key} = ?", id],
0
- :order => 'version' }.merge(options)
0
- end
0
-
0
           # Returns an array of columns that are versioned. See non_versioned_columns
0
           def versioned_columns
0
- self.columns.select { |c| !non_versioned_columns.include?(c.name) }
0
+ @versioned_columns ||= columns.select { |c| !non_versioned_columns.include?(c.name) }
0
           end
0
 
0
           # Returns an instance of the dynamic versioned model
0
@@ -470,17 +424,17 @@ module ActiveRecord #:nodoc:
0
             self.versioned_columns.each do |col|
0
               updated_col = col if !updated_col && %(updated_at updated_on).include?(col.name)
0
               self.connection.add_column versioned_table_name, col.name, col.type,
0
- :limit => col.limit,
0
- :default => col.default,
0
- :scale => col.scale,
0
+ :limit => col.limit,
0
+ :default => col.default,
0
+ :scale => col.scale,
0
                 :precision => col.precision
0
             end
0
 
0
             if type_col = self.columns_hash[inheritance_column]
0
               self.connection.add_column versioned_table_name, versioned_inheritance_column, type_col.type,
0
- :limit => type_col.limit,
0
- :default => type_col.default,
0
- :scale => type_col.scale,
0
+ :limit => type_col.limit,
0
+ :default => type_col.default,
0
+ :scale => type_col.scale,
0
                 :precision => type_col.precision
0
             end
0
 
...
238
239
240
241
242
243
244
245
 
246
247
248
249
250
251
252
253
254
255
256
257
258
 
259
260
261
...
333
334
335
336
337
338
 
339
340
341
...
238
239
240
 
 
 
 
 
241
242
243
244
 
 
 
 
 
 
 
 
 
 
245
246
247
248
...
320
321
322
 
 
 
323
324
325
326
0
@@ -238,24 +238,11 @@ class VersionedTest < Test::Unit::TestCase
0
   end
0
 
0
   def test_find_versions
0
- assert_equal 2, locked_pages(:welcome).versions.size
0
- assert_equal 1, locked_pages(:welcome).versions.find(:all, :conditions => ['title LIKE ?', '%weblog%']).length
0
- assert_equal 2, locked_pages(:welcome).versions.find(:all, :conditions => ['title LIKE ?', '%web%']).length
0
- assert_equal 0, locked_pages(:thinking).versions.find(:all, :conditions => ['title LIKE ?', '%web%']).length
0
- assert_equal 2, locked_pages(:welcome).versions.length
0
+ assert_equal 1, locked_pages(:welcome).versions.find(:all, :conditions => ['title LIKE ?', '%weblog%']).size
0
   end
0
 
0
   def test_find_version
0
- assert_equal page_versions(:welcome_1), Page.find_version(pages(:welcome).id, 23)
0
- assert_equal page_versions(:welcome_2), Page.find_version(pages(:welcome).id, 24)
0
- assert_equal pages(:welcome), Page.find_version(pages(:welcome).id)
0
-
0
- assert_equal page_versions(:welcome_1), pages(:welcome).find_version(23)
0
- assert_equal page_versions(:welcome_2), pages(:welcome).find_version(24)
0
- assert_equal pages(:welcome), pages(:welcome).find_version
0
-
0
- assert_raise(ActiveRecord::RecordNotFound) { Page.find_version(pages(:welcome).id, 1) }
0
- assert_raise(ActiveRecord::RecordNotFound) { Page.find_version(0, 23) }
0
+ assert_equal page_versions(:welcome_1), pages(:welcome).versions.find_by_version(23)
0
   end
0
 
0
   def test_with_sequence
0
@@ -333,8 +320,6 @@ class VersionedTest < Test::Unit::TestCase
0
   end
0
 
0
   def test_should_find_version_count
0
- assert_equal 24, pages(:welcome).versions_count
0
- assert_equal 24, page_versions(:welcome_1).versions_count
0
- assert_equal 24, page_versions(:welcome_2).versions_count
0
+ assert_equal 2, pages(:welcome).versions.size
0
   end
0
 end
0
\ No newline at end of file

Comments

    No one has commented yet.