From 208a1ef73ed300148c93f70d9111fd0ff2cc6306 Mon Sep 17 00:00:00 2001 From: Rodrigo Panachi Date: Tue, 28 Sep 2010 22:34:12 -0300 Subject: [PATCH] performance tunning using 'join table' in tagged_with(:any => true) fetch logic --- .../acts_as_taggable_on/core.rb | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/acts_as_taggable_on/acts_as_taggable_on/core.rb b/lib/acts_as_taggable_on/acts_as_taggable_on/core.rb index 98b42b23f..c6cce78ad 100644 --- a/lib/acts_as_taggable_on/acts_as_taggable_on/core.rb +++ b/lib/acts_as_taggable_on/acts_as_taggable_on/core.rb @@ -80,8 +80,18 @@ def tagged_with(tags, options = {}) conditions << "#{table_name}.#{primary_key} NOT IN (SELECT #{ActsAsTaggableOn::Tagging.table_name}.taggable_id FROM #{ActsAsTaggableOn::Tagging.table_name} JOIN #{ActsAsTaggableOn::Tag.table_name} ON #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.id AND (#{tags_conditions}) WHERE #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = #{quote_value(base_class.name)})" elsif options.delete(:any) - tags_conditions = tag_list.map { |t| sanitize_sql(["#{ActsAsTaggableOn::Tag.table_name}.name LIKE ?", t]) }.join(" OR ") - conditions << "#{table_name}.#{primary_key} IN (SELECT #{ActsAsTaggableOn::Tagging.table_name}.taggable_id FROM #{ActsAsTaggableOn::Tagging.table_name} JOIN #{ActsAsTaggableOn::Tag.table_name} ON #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.id AND (#{tags_conditions}) WHERE #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = #{quote_value(base_class.name)})" + conditions << tag_list.map { |t| sanitize_sql(["#{ActsAsTaggableOn::Tag.table_name}.name LIKE ?", t]) }.join(" OR ") + + tagging_join = " JOIN #{ActsAsTaggableOn::Tagging.table_name}" + + " ON #{ActsAsTaggableOn::Tagging.table_name}.taggable_id = #{table_name}.#{primary_key}" + + " AND #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = #{quote_value(base_class.name)}" + + " JOIN #{ActsAsTaggableOn::Tag.table_name}" + + " ON #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.id" + + tagging_join << " AND " + sanitize_sql(["#{ActsAsTaggableOn::Tagging.table_name}.context = ?", context.to_s]) if context + select_clause = "DISTINCT #{table_name}.*" unless context + + joins << tagging_join else tags = ActsAsTaggableOn::Tag.named_any(tag_list) @@ -115,8 +125,8 @@ def tagged_with(tags, options = {}) group = "#{group_columns} HAVING COUNT(#{taggings_alias}.taggable_id) = #{tags.size}" end - - scoped(:joins => joins.join(" "), + scoped(:select => select_clause, + :joins => joins.join(" "), :group => group, :conditions => conditions.join(" AND "), :order => options[:order], @@ -249,4 +259,4 @@ def save_tags end end end -end \ No newline at end of file +end