module CouchbaseOrm::Persistence

Public Instance Methods

delete(with_cas: false, **options) click to toggle source

Deletes the record in the database and freezes this instance to reflect that no changes should be made (since they can't be persisted). Returns the frozen instance.

The record is simply removed, no callbacks are executed.

# File lib/couchbase-orm/persistence.rb, line 100
def delete(with_cas: false, **options)
    options[:cas] = @__metadata__.cas if with_cas
    self.class.bucket.delete(@__metadata__.key, options)

    @__metadata__.key = nil
    @id = nil

    clear_changes_information
    self.freeze
    self
end
destroy(with_cas: false, **options) click to toggle source

Deletes the record in the database and freezes this instance to reflect that no changes should be made (since they can't be persisted).

There's a series of callbacks associated with destroy.

# File lib/couchbase-orm/persistence.rb, line 116
def destroy(with_cas: false, **options)
    return self if destroyed?
    raise 'model not persisted' unless persisted?

    run_callbacks :destroy do
        destroy_associations!

        options[:cas] = @__metadata__.cas if with_cas
        self.class.bucket.delete(@__metadata__.key, options)

        @__metadata__.key = nil
        @id = nil

        clear_changes_information
        freeze
    end
end
Also aliased as: destroy!
destroy!(with_cas: false, **options)
Alias for: destroy
destroyed?() click to toggle source

Returns true if this object has been destroyed, otherwise returns false.

# File lib/couchbase-orm/persistence.rb, line 62
def destroyed?
    !!(@__metadata__.cas && @__metadata__.key.nil?)
end
exists?()
Alias for: persisted?
new?()
Alias for: new_record?
new_record?() click to toggle source

Returns true if this object hasn't been saved yet – that is, a record for the object doesn't exist in the database yet; otherwise, returns false.

# File lib/couchbase-orm/persistence.rb, line 56
def new_record?
    @__metadata__.cas.nil? && @__metadata__.key.nil?
end
Also aliased as: new?
persisted?() click to toggle source

Returns true if the record is persisted, i.e. it's not a new record and it was not destroyed, otherwise returns false.

# File lib/couchbase-orm/persistence.rb, line 68
def persisted?
    # Changed? is provided by ActiveModel::Dirty
    !!@__metadata__.key
end
Also aliased as: exists?
reload() click to toggle source

Reloads the record from the database.

This method finds record by its key and modifies the receiver in-place:

# File lib/couchbase-orm/persistence.rb, line 196
def reload
    key = @__metadata__.key
    raise "unable to reload, model not persisted" unless key

    resp = self.class.bucket.get(key, quiet: false, extended: true)
    @__attributes__ = ::ActiveSupport::HashWithIndifferentAccess.new(resp.value)
    @__metadata__.key = resp.key
    @__metadata__.cas = resp.cas

    reset_associations
    clear_changes_information
    self
end
save(**options) click to toggle source

Saves the model.

If the model is new, a record gets created in the database, otherwise the existing record gets updated.

# File lib/couchbase-orm/persistence.rb, line 78
def save(**options)
    raise "Cannot save a destroyed document!" if destroyed?
    self.new_record? ? _create_record(**options) : _update_record(**options)
end
save!(**options) click to toggle source

Saves the model.

If the model is new, a record gets created in the database, otherwise the existing record gets updated.

By default, save! always runs validations. If any of them fail CouchbaseOrm::Error::RecordInvalid gets raised, and the record won't be saved.

# File lib/couchbase-orm/persistence.rb, line 90
def save!(**options)
    self.class.fail_validate!(self) unless self.save(**options)
    self
end
touch(**options) click to toggle source

Updates the TTL of the document

# File lib/couchbase-orm/persistence.rb, line 211
def touch(**options)
    res = self.class.bucket.touch(@__metadata__.key, async: false, **options)
    @__metadata__.cas = resp.cas
    self
end
update(hash) click to toggle source

Updates the attributes of the model from the passed-in hash and saves the record. If the object is invalid, the saving will fail and false will be returned.

# File lib/couchbase-orm/persistence.rb, line 147
def update(hash)
    assign_attributes(hash)
    save
end
Also aliased as: update_attributes
update!(hash) click to toggle source

Updates its receiver just like update but calls save! instead of save, so an exception is raised if the record is invalid and saving will fail.

# File lib/couchbase-orm/persistence.rb, line 155
def update!(hash)
    assign_attributes(hash) # Assign attributes is provided by ActiveModel::AttributeAssignment
    save!
end
Also aliased as: update_attributes!
update_attribute(name, value) click to toggle source

Updates a single attribute and saves the record. This is especially useful for boolean flags on existing records. Also note that

  • Validation is skipped.

  • Callbacks are invoked.

# File lib/couchbase-orm/persistence.rb, line 140
def update_attribute(name, value)
    public_send(:"#{name}=", value)
    changed? ? save(validate: false) : true
end
update_attributes(hash)
Alias for: update
update_attributes!(hash)
Alias for: update!
update_columns(with_cas: false, **hash) click to toggle source

Updates the record without validating or running callbacks

# File lib/couchbase-orm/persistence.rb, line 162
def update_columns(with_cas: false, **hash)
    _id = @__metadata__.key
    raise "unable to update columns, model not persisted" unless _id

    assign_attributes(hash)

    options = {extended: true}
    options[:cas] = @__metadata__.cas if with_cas

    # There is a limit of 16 subdoc operations per request
    resp = if hash.length <= 16
        subdoc = self.class.bucket.subdoc(_id)
        hash.each do |key, value|
            subdoc.dict_upsert(key, value)
        end
        subdoc.execute!(options)
    else
        # Fallback to writing the whole document
        @__attributes__[:type] = self.class.design_document
        @__attributes__.delete(:id)
        self.class.bucket.replace(_id, @__attributes__, **options)
    end

    # Ensure the model is up to date
    @__metadata__.key = resp.key
    @__metadata__.cas = resp.cas

    changes_applied
    self
end

Protected Instance Methods

_create_record(**options) click to toggle source
# File lib/couchbase-orm/persistence.rb, line 246
def _create_record(**options)
    return false unless perform_validations(:create, options)

    run_callbacks :create do
        run_callbacks :save do
            # Ensure the type is set
            @__attributes__[:type] = self.class.design_document
            @__attributes__.delete(:id)

            _id = @id || self.class.uuid_generator.next(self)
            resp = self.class.bucket.add(_id, @__attributes__, **options)

            # Ensure the model is up to date
            @__metadata__.key = resp.key
            @__metadata__.cas = resp.cas

            changes_applied
            true
        end
    end
end
_update_record(with_cas: false, **options) click to toggle source
# File lib/couchbase-orm/persistence.rb, line 221
def _update_record(with_cas: false, **options)
    return false unless perform_validations(:update, options)
    return true unless changed?

    run_callbacks :update do
        run_callbacks :save do
            # Ensure the type is set
            @__attributes__[:type] = self.class.design_document
            @__attributes__.delete(:id)

            _id = @__metadata__.key
            options[:cas] = @__metadata__.cas if with_cas

            resp = self.class.bucket.replace(_id, @__attributes__, **options)

            # Ensure the model is up to date
            @__metadata__.key = resp.key
            @__metadata__.cas = resp.cas

            changes_applied
            true
        end
    end
end
perform_validations(context, options = {}) click to toggle source
# File lib/couchbase-orm/persistence.rb, line 268
def perform_validations(context, options = {})
    return valid?(context) if options[:validate] != false
    true
end