module Mongoid::Association::Referenced::Syncable

This module handles the behavior for synchronizing foreign keys between both sides of a many to many associations.

Public Instance Methods

_syncable?(association) click to toggle source

Is the document able to be synced on the inverse side? This is only if the key has changed and the association bindings have not been run.

@example Are the foreign keys syncable?

document._syncable?(association)

@param [ Association ] association The association metadata.

@return [ true, false ] If we can sync.

@since 2.1.0

# File lib/mongoid/association/referenced/syncable.rb, line 23
def _syncable?(association)
  !_synced?(association.foreign_key) && send(association.foreign_key_check)
end
_synced() click to toggle source

Get the synced foreign keys.

@example Get the synced foreign keys.

document._synced

@return [ Hash ] The synced foreign keys.

@since 2.1.0

# File lib/mongoid/association/referenced/syncable.rb, line 35
def _synced
  @_synced ||= {}
end
_synced?(foreign_key) click to toggle source

Has the document been synced for the foreign key?

@example Has the document been synced?

document._synced?

@param [ String ] foreign_key The foreign key.

@return [ true, false ] If we can sync.

@since 2.1.0

# File lib/mongoid/association/referenced/syncable.rb, line 49
def _synced?(foreign_key)
  !!_synced[foreign_key]
end
remove_inverse_keys(association) click to toggle source

Update the inverse keys on destroy.

@example Update the inverse keys.

document.remove_inverse_keys(association)

@param [ Association ] association The association.

@return [ Object ] The updated values.

@since 2.2.1

# File lib/mongoid/association/referenced/syncable.rb, line 63
def remove_inverse_keys(association)
  foreign_keys = send(association.foreign_key)
  unless foreign_keys.nil? || foreign_keys.empty?
    association.criteria(self, foreign_keys).pull(association.inverse_foreign_key => _id)
  end
end
update_inverse_keys(association) click to toggle source

Update the inverse keys for the association.

@example Update the inverse keys

document.update_inverse_keys(association)

@param [ Association ] association The document association.

@return [ Object ] The updated values.

@since 2.1.0

# File lib/mongoid/association/referenced/syncable.rb, line 80
def update_inverse_keys(association)
  if changes.has_key?(association.foreign_key)
    old, new = changes[association.foreign_key]
    adds, subs = new - (old || []), (old || []) - new

    # If we are autosaving we don't want a duplicate to get added - the
    # $addToSet would run previously and then the $push and $each from the
    # inverse on the autosave would cause this. We delete each id from
    # what's in memory in case a mix of id addition and object addition
    # had occurred.
    if association.autosave?
      send(association.name).in_memory.each do |doc|
        adds.delete_one(doc._id)
      end
    end

    unless adds.empty?
      association.criteria(self, adds).without_options.add_to_set(association.inverse_foreign_key => _id)
    end
    unless subs.empty?
      association.criteria(self, subs).without_options.pull(association.inverse_foreign_key => _id)
    end
  end
end