Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
# MongoMapper "embedded document delete" plugin
# By Peter Cooper
#
# Got embedded documents you want to delete? You can delete them as if the
# embedded document collection were an array, but then there's no way to get
# a callback (as far as I could tell). This plugin gives you a call back
# (if you want it) and gives a nicer syntax to deleting embedded docs.
#
# Example:
#
# Let's say we have an Item class that people can "favorite." Favorites are
# stored as embedded items inside User. A "favorited_count" is updated on
# favorite adding/removal.
#
# (I've seen more Mongo-specific techniques at http://www.mongodb.org/display/DOCS/MongoDB+Data+Modeling+and+Rails
# but I haven't tried and don't quite understand them yet..)
#
# class Item
# include MongoMapper::Document
# key :favorited_count, Integer, :default => 0
# end
#
# class Favorite
# include MongoMapper::EmbeddedDocument
#
# key :item_id, ObjectId
# belongs_to :item
#
# after_save :update_favorited_count
#
# def update_favorited_count
# return unless new?
# item.favorited_count += 1
# item.save
# end
#
# def after_delete
# item.favorited_count -= 1
# item.save
# end
# end
#
# # Assume a fully built "favorite" is in @favorite
# # Assume "Frank" is a User object
# Frank.favorites << @favorite
# @item.reload
# assert_equal 1, @item.favorited_count
# @favorite.delete # <--- the key part here..
# @item.reload
# assert_equal 0, @item.favorited_count
#
# Credits
# - "Pluginized" and extended from example code by Ryan Townsend at http://gist.github.com/280921
module EmbeddedDocumentDelete
def delete
rd = _root_document
assoc = self.class.to_s.underscore.pluralize
rd.send("#{assoc}=", rd.send(assoc).delete_if { |n| n.id == id })
rd.save
after_delete if respond_to?(:after_delete)
end
end
MongoMapper::EmbeddedDocument.append_inclusions(EmbeddedDocumentDelete)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment