Module: ActiveRecord::Acts::Versioned::ActMethods

Defined in:
lib/acts_as_versioned.rb

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object

:nodoc:



165
166
167
# File 'lib/acts_as_versioned.rb', line 165

def self.included(base) # :nodoc:
  base.extend ClassMethods
end

Instance Method Details

#changed?(attr_name = nil) ⇒ Boolean Also known as: dirty?

If called with no parameters, gets whether the current model has changed and needs to be versioned. If called with a single parameter, gets whether the parameter has changed.

Returns:

  • (Boolean)


242
243
244
245
246
# File 'lib/acts_as_versioned.rb', line 242

def changed?(attr_name = nil)
  attr_name.nil? ?
    (!self.class.track_changed_attributes or (changed_attributes and changed_attributes.length > 0)) :
    (changed_attributes and changed_attributes.include?(attr_name.to_s))
end

#clear_old_versionsObject

Clears old revisions if a limit is set with the :limit option in acts_as_versioned. Override this method to set your own criteria for clearing old versions.



185
186
187
188
189
190
191
192
# File 'lib/acts_as_versioned.rb', line 185

def clear_old_versions
  return if self.class.max_version_limit == 0
  excess_baggage = send(self.class.version_column).to_i - self.class.max_version_limit
  if excess_baggage > 0
    sql = "DELETE FROM #{self.class.versioned_table_name} WHERE version <= #{excess_baggage} AND #{self.class.versioned_foreign_key} = #{self.id}"
    self.class.versioned_class.connection.execute sql
  end
end

#clone_versioned_model(orig_model, new_model) ⇒ Object

Clones a model. Used when saving a new version or reverting a model’s version.



252
253
254
255
256
257
258
259
260
261
262
# File 'lib/acts_as_versioned.rb', line 252

def clone_versioned_model(orig_model, new_model)
  self.versioned_attributes.each do |key|
    new_model.send("#{key}=", orig_model.attributes[key]) if orig_model.attribute_present?(key)
  end
  
  if orig_model.is_a?(self.class.versioned_class)
    new_model[new_model.class.inheritance_column] = orig_model[self.class.versioned_inheritance_column]
  elsif new_model.is_a?(self.class.versioned_class)
    new_model[self.class.versioned_inheritance_column] = orig_model[orig_model.class.inheritance_column]
  end
end

#find_version(version) ⇒ Object

Finds a specific version of this model.



195
196
197
198
199
# File 'lib/acts_as_versioned.rb', line 195

def find_version(version)
  return version if version.is_a?(self.class.versioned_class)
  return nil if version.is_a?(ActiveRecord::Base)
  find_versions(:conditions => ['version = ?', version], :limit => 1).first
end

#find_versions(options = {}) ⇒ Object

Finds versions of this model. Takes an options hash like find



202
203
204
# File 'lib/acts_as_versioned.rb', line 202

def find_versions(options = {})
  versions.find(:all, options)
end

#revert_to(version) ⇒ Object

Reverts a model to a given version. Takes either a version number or an instance of the versioned model



207
208
209
210
211
212
213
214
215
216
# File 'lib/acts_as_versioned.rb', line 207

def revert_to(version)
  if version.is_a?(self.class.versioned_class)
    return false unless version.send(self.class.versioned_foreign_key) == self.id and !version.new_record?
  else
    return false unless version = find_version(version)
  end
  self.clone_versioned_model(version, self)
  self.send("#{self.class.version_column}=", version.version)
  true
end

#revert_to!(version) ⇒ Object

Reverts a model to a given version and saves the model.

Takes either a version number or an instance of the versioned model



220
221
222
# File 'lib/acts_as_versioned.rb', line 220

def revert_to!(version)
  revert_to(version) ? save_without_revision : false
end

#save_versionObject

Saves a version of the model if applicable



170
171
172
# File 'lib/acts_as_versioned.rb', line 170

def save_version
  save_version_on_create if save_version?
end

#save_version?Boolean

Checks whether a new version shall be saved or not. Calls version_condition_met? and changed?.

Returns:

  • (Boolean)


265
266
267
# File 'lib/acts_as_versioned.rb', line 265

def save_version?
  version_condition_met? and changed?
end

#save_version_on_createObject

Saves a version of the model in the versioned table. This is called in the after_save callback by default



175
176
177
178
179
180
181
# File 'lib/acts_as_versioned.rb', line 175

def save_version_on_create
  rev = self.class.versioned_class.new
  self.clone_versioned_model(self, rev)
  rev.version = send(self.class.version_column)
  rev.send("#{self.class.versioned_foreign_key}=", self.id)
  rev.save
end

#save_without_revisionObject

Temporarily turns off Optimistic Locking while saving. Used when reverting so that a new version is not created.



225
226
227
228
229
230
231
232
233
# File 'lib/acts_as_versioned.rb', line 225

def save_without_revision
  old_lock_value = ActiveRecord::Base.lock_optimistically
  ActiveRecord::Base.lock_optimistically = false if old_lock_value
  disable_acts_as_versioned_callbacks
  save_result = self.save
  enable_acts_as_versioned_callbacks
  ActiveRecord::Base.lock_optimistically = true if old_lock_value
  save_result
end

#version_condition_met?Boolean

Checks condition set in the :if option to check whether a revision should be created or not. Override this for custom version condition checking.

Returns:

  • (Boolean)


271
272
273
274
275
276
277
278
279
280
# File 'lib/acts_as_versioned.rb', line 271

def version_condition_met?
  case
  when version_condition.is_a?(Symbol)
    send(version_condition)
  when version_condition.respond_to?(:call) && (version_condition.arity == 1 || version_condition.arity == -1)
    version_condition.call(self)
  else
    version_condition
  end          
end

#versioned_attributesObject

Returns an array of attribute keys that are versioned. See non_versioned_fields



236
237
238
# File 'lib/acts_as_versioned.rb', line 236

def versioned_attributes
  self.attributes.keys.select { |k| !self.class.non_versioned_fields.include?(k) }
end