Class: ActsAsRevisionable::RevisionRecord
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- ActsAsRevisionable::RevisionRecord
- Defined in:
- lib/acts_as_revisionable/revision_record.rb
Instance Attribute Summary collapse
-
#data_encoding ⇒ Object
readonly
Returns the value of attribute data_encoding.
Class Method Summary collapse
-
.create_table ⇒ Object
Create the table to store revision records.
-
.empty_trash(revisionable_type, max_age) ⇒ Object
Empty the trash by deleting records older than the specified maximum age in seconds.
-
.find_revision(klass, id, revision) ⇒ Object
Find a specific revision record.
-
.last_revision(klass, id, revision = nil) ⇒ Object
Find the last revision record for a class.
-
.truncate_revisions(revisionable_type, revisionable_id, options) ⇒ Object
Truncate the revisions for a record.
-
.update_version_1_table ⇒ Object
Update a version 1.0.x table to the latest version.
Instance Method Summary collapse
-
#initialize(record, encoding = :ruby) ⇒ RevisionRecord
constructor
Create a revision record based on a record passed in.
-
#restore ⇒ Object
Restore the revision to the original record.
-
#revision_attributes ⇒ Object
Returns the attributes that are saved in the revision.
-
#trash! ⇒ Object
Mark this revision as being trash.
Constructor Details
#initialize(record, encoding = :ruby) ⇒ RevisionRecord
Create a revision record based on a record passed in. The attributes of the original record will be serialized. If it uses the acts_as_revisionable behavior, associations will be revisioned as well.
77 78 79 80 81 82 83 84 |
# File 'lib/acts_as_revisionable/revision_record.rb', line 77 def initialize(record, encoding = :ruby) super({}) @data_encoding = encoding self.revisionable_type = record.class.base_class.name self.revisionable_id = record.id associations = record.class.revisionable_associations if record.class.respond_to?(:revisionable_associations) self.data = Zlib::Deflate.deflate(serialize_hash(serialize_attributes(record, associations))) end |
Instance Attribute Details
#data_encoding ⇒ Object (readonly)
Returns the value of attribute data_encoding.
8 9 10 |
# File 'lib/acts_as_revisionable/revision_record.rb', line 8 def data_encoding @data_encoding end |
Class Method Details
.create_table ⇒ Object
Create the table to store revision records.
48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/acts_as_revisionable/revision_record.rb', line 48 def create_table connection.create_table table_name do |t| t.string :revisionable_type, :null => false, :limit => 100 t.integer :revisionable_id, :null => false t.integer :revision, :null => false t.binary :data, :limit => (connection.adapter_name.match(/mysql/i) ? 5.megabytes : nil) t. :created_at, :null => false t.boolean :trash, :default => false end connection.add_index table_name, :revisionable_id, :name => "#{table_name}_id" connection.add_index table_name, [:revisionable_type, :created_at, :trash], :name => "#{table_name}_type_and_created_at" end |
.empty_trash(revisionable_type, max_age) ⇒ Object
Empty the trash by deleting records older than the specified maximum age in seconds. The revisionable_type
argument specifies the class to delete revision records for.
41 42 43 44 45 |
# File 'lib/acts_as_revisionable/revision_record.rb', line 41 def empty_trash(revisionable_type, max_age) sql = "revisionable_id IN (SELECT revisionable_id from #{table_name} WHERE created_at <= ? AND revisionable_type = ? AND trash = ?) AND revisionable_type = ?" args = [max_age.ago, revisionable_type.name, true, revisionable_type.name] delete_all([sql] + args) end |
.find_revision(klass, id, revision) ⇒ Object
Find a specific revision record.
14 15 16 |
# File 'lib/acts_as_revisionable/revision_record.rb', line 14 def find_revision(klass, id, revision) find(:first, :conditions => {:revisionable_type => klass.base_class.to_s, :revisionable_id => id, :revision => revision}) end |
.last_revision(klass, id, revision = nil) ⇒ Object
Find the last revision record for a class.
19 20 21 |
# File 'lib/acts_as_revisionable/revision_record.rb', line 19 def last_revision(klass, id, revision = nil) find(:first, :conditions => {:revisionable_type => klass.base_class.to_s, :revisionable_id => id}, :order => "revision DESC") end |
.truncate_revisions(revisionable_type, revisionable_id, options) ⇒ Object
Truncate the revisions for a record. Available options are :limit and :max_age.
24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/acts_as_revisionable/revision_record.rb', line 24 def truncate_revisions(revisionable_type, revisionable_id, ) return unless [:limit] || [:minimum_age] conditions = ['revisionable_type = ? AND revisionable_id = ?', revisionable_type.base_class.to_s, revisionable_id] if [:minimum_age] conditions.first << ' AND created_at <= ?' conditions << [:minimum_age].ago end start_deleting_revision = find(:first, :conditions => conditions, :order => 'revision DESC', :offset => [:limit]) if start_deleting_revision delete_all(['revisionable_type = ? AND revisionable_id = ? AND revision <= ?', revisionable_type.base_class.to_s, revisionable_id, start_deleting_revision.revision]) end end |
.update_version_1_table ⇒ Object
Update a version 1.0.x table to the latest version. This method only needs to be called from a migration if you originally created the table with a version 1.0.x version of the gem.
64 65 66 67 68 69 70 71 72 |
# File 'lib/acts_as_revisionable/revision_record.rb', line 64 def update_version_1_table # Added in version 1.1.0 connection.add_column(:revision_records, :trash, :boolean, :default => false) connection.add_index :revision_records, :revisionable_id, :name => "#{table_name}_id" connection.add_index :revision_records, [:revisionable_type, :created_at, :trash], :name => "#{table_name}_type_and_created_at" # Removed in 1.1.0 connection.remove_index(:revision_records, :name => "revisionable") end |
Instance Method Details
#restore ⇒ Object
Restore the revision to the original record. If any errors are encountered restoring attributes, they will be added to the errors object of the restored record.
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/acts_as_revisionable/revision_record.rb', line 95 def restore restore_class = self.revisionable_type.constantize # Check if we have a type field, if yes, assume single table inheritance and restore the actual class instead of the stored base class sti_type = self.revision_attributes[restore_class.inheritance_column] if sti_type begin if !restore_class.store_full_sti_class && !sti_type.start_with?("::") sti_type = "#{restore_class.parent.name}::#{sti_type}" end restore_class = sti_type.constantize rescue NameError => e raise e # Seems our assumption was wrong and we have no STI end end record = restore_class.new restore_record(record, revision_attributes) return record end |
#revision_attributes ⇒ Object
Returns the attributes that are saved in the revision.
87 88 89 90 91 |
# File 'lib/acts_as_revisionable/revision_record.rb', line 87 def revision_attributes return nil unless self.data uncompressed = Zlib::Inflate.inflate(self.data) deserialize_hash(uncompressed) end |
#trash! ⇒ Object
Mark this revision as being trash. When trash records are restored, all their revision history is restored as well.
119 120 121 |
# File 'lib/acts_as_revisionable/revision_record.rb', line 119 def trash! update_attribute(:trash, true) end |