From e07e0b92e2d2020093f9b9b382b5e654db22ca28 Mon Sep 17 00:00:00 2001 From: Aaron Qian Date: Tue, 20 Dec 2011 00:18:13 -0800 Subject: [PATCH] fixed real time aggregation --- .../aggregation_strategy/real_time.rb | 56 ++++++++++--------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/lib/mongoid/taggable_with_context/aggregation_strategy/real_time.rb b/lib/mongoid/taggable_with_context/aggregation_strategy/real_time.rb index 80b7ba9..885e0f4 100644 --- a/lib/mongoid/taggable_with_context/aggregation_strategy/real_time.rb +++ b/lib/mongoid/taggable_with_context/aggregation_strategy/real_time.rb @@ -3,8 +3,8 @@ module RealTime extend ActiveSupport::Concern included do - set_callback :save, :after, :update_tags_aggregation, :if => :tags_changed? - set_callback :destroy, :after, :update_tags_aggregation + set_callback :save, :after, :update_tags_aggregations_on_save + set_callback :destroy, :after, :update_tags_aggregations_on_destroy end module ClassMethods @@ -27,34 +27,40 @@ def tags_with_weight_for(context, conditions={}) end protected + + def update_tags_aggregation(context_array_field, old_tags=[], new_tags=[]) + context = context_array_to_context_hash[context_array_field] + coll = self.class.db.collection(self.class.aggregation_collection_for(context)) - def changed_tag_arrays - tag_array_attributes & changes.keys.map(&:to_sym) + old_tags ||= [] + new_tags ||= [] + unchanged_tags = old_tags & new_tags + tags_removed = old_tags - unchanged_tags + tags_added = new_tags - unchanged_tags + + tags_removed.each do |tag| + coll.update({:_id => tag}, {'$inc' => {:value => -1}}, :upsert => true) + end + + tags_added.each do |tag| + coll.update({:_id => tag}, {'$inc' => {:value => 1}}, :upsert => true) + end end - def tags_changed? - !changed_tag_arrays.empty? + def update_tags_aggregations_on_save + tag_array_attributes.each do |context_array| + next if changes[context_array].nil? + + old_tags, new_tags = changes[context_array] + update_tags_aggregation(context_array, old_tags, new_tags) + end end - def update_tags_aggregation - changed_tag_arrays.each do |field_name| - context = context_array_to_context_hash[field_name] - coll = self.class.db.collection(self.class.aggregation_collection_for(context)) - field_name = self.class.tag_options_for(context)[:array_field] - old_tags, new_tags = changes["#{field_name}"] - old_tags ||= [] - new_tags ||= [] - unchanged_tags = old_tags & new_tags - tags_removed = old_tags - unchanged_tags - tags_added = new_tags - unchanged_tags - - tags_removed.each do |tag| - coll.update({:_id => tag}, {'$inc' => {:value => -1}}, :upsert => true) - end - - tags_added.each do |tag| - coll.update({:_id => tag}, {'$inc' => {:value => 1}}, :upsert => true) - end + def update_tags_aggregations_on_destroy + tag_array_attributes.each do |context_array| + old_tags = send context_array + new_tags = [] + update_tags_aggregation(context_array, old_tags, new_tags) end end end