module Mongoid::Association::Referenced::Syncable
This module handles the behaviour for synchronizing foreign keys between both sides of a many to many relations.
Public Instance Methods
Is the document able to be synced on the inverse side? This is only if the key has changed and the relation 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 20 def _syncable?(association) !_synced?(association.foreign_key) && send(association.foreign_key_check) end
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 32 def _synced @_synced ||= {} end
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 46 def _synced?(foreign_key) !!_synced[foreign_key] end
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 60 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 the inverse keys for the relation.
@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 77 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