module ActiveModelPersistence::Persistence

This mixin adds the ability to store and manage Ruby objects in an in-memory object store. These objects are commonly called ‘models’.

@example

class ModelExample
  include ActiveModelPersistence::Persistence
  attribute :id, :integer
  attribute :name, :string
  index :id, unique: true
  validates :id, presence: true
end

# Creating a model instance with `.new` does not save it to the object store
#
m = ModelExample.new(id: 1, name: 'James')
m.new_record? # => true
m.persisted? # => false
m.destroyed? # => false

# `save` will save the object to the object store
#
m.save
m.new_record? # => false
m.persisted? # => true
m.destroyed? # => false

# Once an object is persisted, it can be fetched from the object store using `.find`
# and `.find_by_*` methods.
m2 = ModelExample.find(1)
m == m2 # => true

m2 = ModelExample.find_by_id(1)
m == m2 # => true

# `destroy` will remove the object from the object store
#
m.destroy
m.new_record? # => true
m.persisted? # => false
m.destroyed? # => true

Public Instance Methods

==(other) click to toggle source
# File lib/active_model_persistence/persistence.rb, line 381
def ==(other)
  attributes == other.attributes
end
destroy() click to toggle source

Deletes the object from the object store

This model object is frozen to reflect that no changes should be made since they can’t be persisted.

@example

ModelExample.create(id: 1, name: 'James')
object = ModelExample.create(id: 2, name: 'Frank')
object.destroyed? #=> false
ModelExample.all.count #=> 2
object.destroy
object.destroyed? #=> true
ModelExample.all.count #=> 1
ModelExample.all.first.name #=> 'James'

@return [void]

# File lib/active_model_persistence/persistence.rb, line 371
def destroy
  if persisted?
    remove_from_indexes
    self.class.object_array.delete_if { |o| o.primary_key == primary_key }
  end
  @new_record = false
  @destroyed = true
  freeze
end
destroyed?() click to toggle source

Returns true if this object has been destroyed

@example Destroying a saved model object

object = ModelExample.new(id: 1, name: 'James')
object.destroyed? #=> false
object.save
object.destroyed? #=> false
object.destroy
object.destroyed? #=> true

@example Destroying a unsaved model object

object = ModelExample.new(id: 1, name: 'James')
object.destroyed? #=> false
object.destroy
object.destroyed? #=> true

@return [Boolean] true if this object has been destroyed

# File lib/active_model_persistence/persistence.rb, line 277
def destroyed?
  if instance_variable_defined?(:@destroyed)
    @destroyed
  else
    @destroyed = false
  end
end
new_record?() click to toggle source

Returns true if this object hasn’t been saved or destroyed yet

@example

object = ModelExample.new(id: 1, name: 'James')
object.new_record? #=> true
object.save
object.new_record? #=> false
object.destroy
object.new_record? #=> false

@return [Boolean] true if this object hasn’t been saved yet

# File lib/active_model_persistence/persistence.rb, line 251
def new_record?
  if instance_variable_defined?(:@new_record)
    @new_record
  else
    @new_record = true
  end
end
persisted?() click to toggle source

Returns true if the record is persisted in the object store

@example

object = ModelExample.new(id: 1, name: 'James')
object.persisted? #=> false
object.save
object.persisted? #=> true
object.destroy
object.persisted? #=> false

@return [Boolean] true if the record is persisted in the object store

# File lib/active_model_persistence/persistence.rb, line 297
def persisted?
  !(new_record? || destroyed?)
end
save(**options, &block) click to toggle source

Saves the model object in the object store and updates all indexes

@example

ModelExample.all.count #=> 0
object = ModelExample.new(id: 1, name: 'James')
ModelExample.all.count #=> 0
object.save
ModelExample.all.count #=> 1

@param options [Hash] save options (currently unused) @param block [Proc] a block to call after the save

@yield [self] a block to call after the save @yieldparam saved_model [self] the model object after it was saved @yieldreturn [void]

@return [Boolean] true if the model object was saved

# File lib/active_model_persistence/persistence.rb, line 319
def save(**options, &block)
  save!(**options, &block)
rescue ModelError
  false
else
  true
end
save!(**_options, &block) click to toggle source

Calls save and raises an error if save returns false

@example

object = ModelExample.new(id: nil, name: 'James')
object.save! #=> raises ObjectNotSavedError

@param _options [Hash] save options (currently unused)

@param block [Proc] a block to call after the save

@yield [self] a block to call after the save @yieldparam saved_model [self] the model object after it was saved @yieldreturn [void]

@raise [ObjectNotSavedError] if the model object was not saved

@return [Boolean] returns true or raises an error

# File lib/active_model_persistence/persistence.rb, line 345
def save!(**_options, &block)
  raise ObjectDestroyedError if destroyed?
  raise ObjectNotValidError, self unless valid?

  new_record? ? _create(&block) : _update(&block)
  update_indexes
  true
end
update(attributes) click to toggle source

Updates the attributes of the model and saves it

The attributes are updated from the passed in hash. If the object is invalid, the save will fail and false will be returned.

@example

object = ModelExample.create(id: 1, name: 'James')
object.update(name: 'Frank')
object.find(1).name #=> 'Frank'

@param attributes [Hash] the attributes to update

@return [Boolean] true if the model object was saved, otherwise false

# File lib/active_model_persistence/persistence.rb, line 399
def update(attributes)
  update!(attributes)
rescue ModelError
  false
else
  true
end
update!(attributes) click to toggle source

Updates just like update but an exception is raised of the model is invalid

@example

object = ModelExample.create(id: 1, name: 'James')
object.update!(id: nil) #=> raises ObjectNotSavedError

@param attributes [Hash] the attributes to update

@return [Boolean] true if the model object was saved, otherwise an error is raised

@raise [ObjectNotValidError] if the model object is invalid @raise [ObjectDestroyedError] if the model object was previously destroyed

# File lib/active_model_persistence/persistence.rb, line 420
def update!(attributes)
  raise ObjectDestroyedError if destroyed?

  assign_attributes(attributes)
  save!
end

Private Instance Methods

_create() { |self| ... } click to toggle source

Creates a record with values matching those of the instance attributes and returns its id.

@return [Object] the primary_key of the created object

@api private

# File lib/active_model_persistence/persistence.rb, line 436
def _create
  return false unless primary_key?
  raise UniqueConstraintError if primary_key_index.include?(primary_key)

  self.class.object_array << self

  @new_record = false

  yield(self) if block_given?

  primary_key
end
_update() { |self| ... } click to toggle source

Updates an object that is already in the object store

@return [Boolean] true if the object was update successfully, otherwise raises a ModelError

@api private

# File lib/active_model_persistence/persistence.rb, line 455
def _update
  raise RecordNotFound unless primary_key_index.include?(primary_key)

  yield(self) if block_given?

  true
end