Created
March 30, 2011 22:17
-
-
Save paddyinpdx/895428 to your computer and use it in GitHub Desktop.
Mongoid 2.0 Workaround Methods for Update/Delete actions when using references_and_referenced_in_many
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# tag.rb | |
class Tag | |
include Mongoid::Document | |
# Fields | |
field :title | |
# Associations | |
references_and_referenced_in_many :related, :class_name => "Tag" | |
before_save :flatten_related_tags # Needed for cases where related_ids == [[]] | |
before_destroy :delete_from_related_tags | |
before_destroy :delete_from_tagged_content | |
private | |
def delete_from_tagged_content | |
[Article,Pdf,Link].each do |model| | |
model.any_in(:tag_id => [self.id]).each do |item| | |
item.tag_id.delete(self.id) | |
item.save | |
end | |
end | |
end | |
def delete_from_related_tags | |
Tag.any_in(:related_ids => [self.id]).each do |_tag| | |
_tag.related.delete(self) | |
_tag.save | |
end | |
end | |
def flatten_related_tags | |
if defined?(self.related_ids) | |
self.related_ids.delete(self.id) | |
self.related_ids.flatten! | |
self.related_ids.uniq! | |
end | |
end | |
end | |
# tags_controller.rb | |
# | |
# Work around for fact that with Mongoid you cannot just use tag ids when setting relations. You have to work | |
# with the actual tag object. So I can't just pass params[:tag][:related_ids] to update the @tag.related_ids property. | |
# I have to convert the related_ids to related tags and update @tag.related. | |
def updateRelatedTags(current_tag, params_related_ids) | |
# First compare the existing related ids with the ones passed as a param. If a currently stored related_id is | |
# missing from the params, it has been deleted as a related tag. So *that* tag needs to have *this* tag's relation | |
# deleted as well. | |
deleted_related_tags = (current_tag.related_ids || []) - (params_related_ids || []) | |
if deleted_related_tags.any? | |
deleted_related_tags.each do |related_tag_id| | |
related_tag = Tag.criteria.for_ids(related_tag_id).first | |
if !related_tag.nil? | |
related_tag.related.delete(current_tag) | |
related_tag.save | |
end | |
end | |
end | |
# Now update this tag's related tags using its related property, not its related_ids property. If you use the former | |
# the tag being related will not store a relation to this tag. | |
if !params_related_ids.nil? && params_related_ids.any? | |
params_related_ids.each do |related_tag_id| | |
related_tag = Tag.criteria.for_ids(related_tag_id).first | |
if !related_tag.nil? | |
# This won't work if you try tag.related_ids.push(related_tag_id) | |
current_tag.related.push(related_tag) | |
end | |
end | |
else | |
# No related ids were passed in, so there are no longer any relations | |
current_tag.related = [] | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment