Module: ActiveRecord::Acts::Versioned::ActMethods
- Defined in:
- vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb
Defined Under Namespace
Modules: ClassMethods
Class Method Summary
-
+ (Object) included(base)
:nodoc:.
Instance Method Summary
-
- (Boolean) changed?(attr_name = nil)
(also: #dirty?)
If called with no parameters, gets whether the current model has changed and needs to be versioned.
-
- (Object) clear_old_versions
Clears old revisions if a limit is set with the :limit option in acts_as_versioned.
-
- (Object) clone_versioned_model(orig_model, new_model)
Clones a model.
-
- (Object) empty_callback
:nodoc:.
-
- (Object) find_version(version = nil)
Finds a specific version of this record.
-
- (Object) revert_to(version)
Reverts a model to a given version.
-
- (Object) revert_to!(version)
Reverts a model to a given version and saves the model.
-
- (Object) save_version
Saves a version of the model if applicable.
-
- (Boolean) save_version?
Checks whether a new version shall be saved or not.
-
- (Object) save_version_on_create
Saves a version of the model in the versioned table.
-
- (Object) save_without_revision
Temporarily turns off Optimistic Locking while saving.
- - (Object) save_without_revision!
-
- (Boolean) version_condition_met?
Checks condition set in the :if option to check whether a revision should be created or not.
-
- (Object) versioned_attributes
Returns an array of attribute keys that are versioned.
- - (Object) versions_count
-
- (Object) without_locking(&block)
Turns off optimistic locking for the duration of the block.
-
- (Object) without_revision(&block)
Executes the block with the versioning callbacks disabled.
Class Method Details
+ (Object) included(base)
:nodoc:
286 287 288 |
# File 'vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb', line 286 def self.included(base) # :nodoc: base.extend ClassMethods end |
Instance Method Details
- (Boolean) changed?(attr_name = nil) 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.
365 366 367 368 369 |
# File 'vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb', line 365 def changed?(attr_name = nil) attr_name.nil? ? (!self.class.track_altered_attributes || (altered_attributes && altered_attributes.length > 0)) : (altered_attributes && altered_attributes.include?(attr_name.to_s)) end |
- (Object) clear_old_versions
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.
311 312 313 314 315 316 317 318 |
# File 'vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb', line 311 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 |
- (Object) clone_versioned_model(orig_model, new_model)
Clones a model. Used when saving a new version or reverting a model’s version.
375 376 377 378 379 380 381 382 383 384 385 |
# File 'vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb', line 375 def clone_versioned_model(orig_model, new_model) self.versioned_attributes.each do |key| new_model.send("#{key}=", orig_model.send(key)) if orig_model.has_attribute?(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 |
- (Object) empty_callback
:nodoc:
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 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 |
# File 'vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb', line 425 def empty_callback() end protected # sets the new version before saving, unless you're using optimistic locking. In that case, let it take care of the version. def set_new_version self.send("#{self.class.version_column}=", self.next_version) if new_record? || (!locking_enabled? && save_version?) end # Gets the next available version for the current record, or 1 for a new record def next_version return 1 if new_record? (versions.calculate(:max, :version) || 0) + 1 end # clears current changed attributes. Called after save. def clear_altered_attributes self.altered_attributes = [] end def write_changed_attribute(attr_name, attr_value) # Convert to db type for comparison. Avoids failing Float<=>String comparisons. attr_value_for_db = self.class.columns_hash[attr_name.to_s].type_cast(attr_value) (self.altered_attributes ||= []) << attr_name.to_s unless self.changed?(attr_name) || self.send(attr_name) == attr_value_for_db write_attribute(attr_name, attr_value_for_db) end module ClassMethods # Finds a specific version of a specific row of this model def find_version(id, version = nil) return find(id) unless version conditions = ["#{versioned_foreign_key} = ? AND version = ?", id, version] = { :conditions => conditions, :limit => 1 } if result = find_versions(id, ).first result else raise RecordNotFound, "Couldn't find #{name} with ID=#{id} and VERSION=#{version}" end end # Finds versions of a specific model. Takes an options hash like <tt>find</tt> def find_versions(id, = {}) versioned_class.find :all, { :conditions => ["#{versioned_foreign_key} = ?", id], :order => 'version' }.merge() end # Returns an array of columns that are versioned. See non_versioned_columns def versioned_columns self.columns.select { |c| !non_versioned_columns.include?(c.name) } end # Returns an instance of the dynamic versioned model def versioned_class const_get versioned_class_name end # Rake migration task to create the versioned table using options passed to acts_as_versioned def create_versioned_table( = {}) # create version column in main table if it does not exist if !self.content_columns.find { |c| %w(version lock_version).include? c.name } self.connection.add_column table_name, :version, :integer end self.connection.create_table(versioned_table_name, ) do |t| t.column versioned_foreign_key, :integer t.column :version, :integer end updated_col = nil self.versioned_columns.each do |col| updated_col = col if !updated_col && %(updated_at updated_on).include?(col.name) self.connection.add_column versioned_table_name, col.name, col.type, :limit => col.limit, :default => col.default, :scale => col.scale, :precision => col.precision end if type_col = self.columns_hash[inheritance_column] self.connection.add_column versioned_table_name, versioned_inheritance_column, type_col.type, :limit => type_col.limit, :default => type_col.default, :scale => type_col.scale, :precision => type_col.precision end if updated_col.nil? self.connection.add_column versioned_table_name, :updated_at, :timestamp end end # Rake migration task to drop the versioned table def drop_versioned_table self.connection.drop_table versioned_table_name end # Executes the block with the versioning callbacks disabled. # # Foo.without_revision do # @foo.save # end # def without_revision(&block) class_eval do CALLBACKS.each do |attr_name| alias_method "orig_#{attr_name}".to_sym, attr_name alias_method attr_name, :empty_callback end end block.call ensure class_eval do CALLBACKS.each do |attr_name| alias_method attr_name, "orig_#{attr_name}".to_sym end end end # Turns off optimistic locking for the duration of the block # # Foo.without_locking do # @foo.save # end # def without_locking(&block) current = ActiveRecord::Base.lock_optimistically ActiveRecord::Base.lock_optimistically = false if current result = block.call ActiveRecord::Base.lock_optimistically = true if current result end end |
- (Object) find_version(version = nil)
Finds a specific version of this record
291 292 293 |
# File 'vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb', line 291 def find_version(version = nil) self.class.find_version(id, version) end |
- (Object) revert_to(version)
Reverts a model to a given version. Takes either a version number or an instance of the versioned model
325 326 327 328 329 330 331 332 333 334 |
# File 'vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb', line 325 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 = versions.find_by_version(version) end self.clone_versioned_model(version, self) self.send("#{self.class.version_column}=", version.version) true end |
- (Object) revert_to!(version)
Reverts a model to a given version and saves the model. Takes either a version number or an instance of the versioned model
338 339 340 |
# File 'vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb', line 338 def revert_to!(version) revert_to(version) ? save_without_revision : false end |
- (Object) save_version
Saves a version of the model if applicable
296 297 298 |
# File 'vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb', line 296 def save_version save_version_on_create if save_version? end |
- (Boolean) save_version?
Checks whether a new version shall be saved or not. Calls version_condition_met? and changed?.
388 389 390 |
# File 'vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb', line 388 def save_version? version_condition_met? && changed? end |
- (Object) save_version_on_create
Saves a version of the model in the versioned table. This is called in the after_save callback by default
301 302 303 304 305 306 307 |
# File 'vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb', line 301 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 |
- (Object) save_without_revision
Temporarily turns off Optimistic Locking while saving. Used when reverting so that a new version is not created.
343 344 345 346 347 348 |
# File 'vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb', line 343 def save_without_revision save_without_revision! true rescue false end |
- (Object) save_without_revision!
350 351 352 353 354 355 356 |
# File 'vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb', line 350 def save_without_revision! without_locking do without_revision do save! end end end |
- (Boolean) version_condition_met?
Checks condition set in the :if option to check whether a revision should be created or not. Override this for custom version condition checking.
394 395 396 397 398 399 400 401 402 403 |
# File 'vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb', line 394 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 |
- (Object) versioned_attributes
Returns an array of attribute keys that are versioned. See non_versioned_columns
359 360 361 |
# File 'vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb', line 359 def versioned_attributes self.attributes.keys.select { |k| !self.class.non_versioned_columns.include?(k) } end |
- (Object) versions_count
320 321 322 |
# File 'vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb', line 320 def versions_count version end |
- (Object) without_locking(&block)
Turns off optimistic locking for the duration of the block
@foo.without_locking do @foo.save end
421 422 423 |
# File 'vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb', line 421 def without_locking(&block) self.class.without_locking(&block) end |
- (Object) without_revision(&block)
Executes the block with the versioning callbacks disabled.
@foo.without_revision do @foo.save end
411 412 413 |
# File 'vendor/plugins/acts_as_versioned/lib/acts_as_versioned.rb', line 411 def without_revision(&block) self.class.without_revision(&block) end |