lib/mongoid/relations/referenced/many_to_many.rb in mongoid-2.0.0.rc.4 vs lib/mongoid/relations/referenced/many_to_many.rb in mongoid-2.0.0.rc.5

- old
+ new

@@ -3,59 +3,24 @@ module Relations #:nodoc: module Referenced #:nodoc: # This class defines the behaviour for all relations that are a # many-to-many between documents in different collections. - class ManyToMany < Relations::Many + class ManyToMany < Referenced::Many - # Binds the base object to the inverse of the relation. This is so we - # are referenced to the actual objects themselves and dont hit the - # database twice when setting the relations up. - # - # This is called after first creating the relation, or if a new object - # is set on the relation. - # - # @example Bind the relation. - # person.preferences.bind - # - # @param [ Hash ] options The options to bind with. - # - # @option options [ true, false ] :building Are we in build mode? - # @option options [ true, false ] :continue Continue binding the - # inverse? - # - # @since 2.0.0.rc.1 - def bind(options = {}) - loaded and binding.bind(options) - target.map(&:save) if base.persisted? && !options[:building] - end - - # Clear the relation. Will delete the documents from the db if they are - # already persisted. - # - # @example Clear the relation. - # person.preferences.clear - # - # @return [ Many ] The relation emptied. - def clear - tap do |relation| - relation.unbind(default_options) - target.clear - end - end - # Delete a single document from the relation. # # @example Delete a document. # person.preferences.delete(preference) # # @param [ Document ] document The document to delete. # # @since 2.0.0.rc.1 def delete(document, options = {}) - target.delete(document) - binding.unbind_one(document, options) + target.delete(document).tap do |doc| + binding.unbind_one(doc, default_options.merge!(options)) if doc + end end # Deletes all related documents from the database given the supplied # conditions. # @@ -124,33 +89,20 @@ "_id" => { "$in" => base.send(metadata.foreign_key) } ) klass.find(arg, :conditions => selector) end - # Instantiate a new references_many relation. Will set the foreign key - # and the base on the inverse object. - # - # @example Create the new relation. - # Referenced::ManyToMany.new(base, target, metadata) - # - # @param [ Document ] base The document this relation hangs off of. - # @param [ Array<Document> ] target The target of the relation. - # @param [ Metadata ] metadata The relation's metadata. - def initialize(base, target, metadata) - init(base, target, metadata) - end - # Removes all associations between the base document and the target # documents by deleting the foreign keys and the references, orphaning # the target documents in the process. # # @example Nullify the relation. # person.preferences.nullify # # @since 2.0.0.rc.1 def nullify - loaded and target.each do |doc| + load! and target.each do |doc| base.send(metadata.foreign_key).delete(doc.id) dereference(doc) end target.clear end @@ -164,11 +116,11 @@ # person.posts.substitute(new_name) # # @param [ Array<Document> ] target The replacement target. # @param [ Hash ] options The options to bind with. # - # @option options [ true, false ] :building Are we in build mode? + # @option options [ true, false ] :binding Are we in build mode? # @option options [ true, false ] :continue Continue binding the # inverse? # # @return [ Many ] The relation. # @@ -193,11 +145,11 @@ # @example Unbind the target. # person.posts.unbind # # @param [ Hash ] options The options to bind with. # - # @option options [ true, false ] :building Are we in build mode? + # @option options [ true, false ] :binding Are we in build mode? # @option options [ true, false ] :continue Continue binding the # inverse? # # @since 2.0.0.rc.1 def unbind(options = {}) @@ -206,25 +158,10 @@ [] end private - # Appends the document to the target array, updating the index on the - # document at the same time. - # - # @example Append the document to the relation. - # relation.append(document) - # - # @param [ Document ] document The document to append to the target. - # - # @since 2.0.0.rc.1 - def append(document, options = {}) - loaded and target.push(document) - characterize_one(document) - binding.bind_one(document, options) - end - # Instantiate the binding associated with this relation. # # @example Get the binding. # relation.binding([ address ]) # @@ -243,11 +180,11 @@ # @example Get a criteria for the relation. # relation.criteria # # @return [ Criteria ] A new criteria. def criteria - metadata.klass.criteria(false) + metadata.klass.any_in(metadata.inverse_foreign_key => [ base.id ]) end # Dereferences the supplied document from the base of the relation. # # @example Dereference the document. @@ -256,24 +193,9 @@ # @param [ Document ] document The document to dereference. def dereference(document) document.send(metadata.inverse_foreign_key).delete(base.id) document.send(metadata.inverse(document)).target.delete(base) document.save - end - - # Will load the target into an array if the target had not already been - # loaded. - # - # @example Load the relation into memory. - # relation.loaded - # - # @return [ ManyToMany ] The relation. - # - # @since 2.0.0.rc.1 - def loaded - tap do |relation| - relation.target = target.entries if target.is_a?(Mongoid::Criteria) - end end class << self # Return the builder that is responsible for generating the documents