Permalink
Browse files

Use faster group columns if not running on postgresql

  • Loading branch information...
1 parent f836c91 commit c31c2e53b1cb8484ad466c3fbb853f2e665c2390 @tomeric tomeric committed May 19, 2010
@@ -91,7 +91,6 @@ def all_tag_counts(options = {})
joins = joins.reverse if ActiveRecord::VERSION::MAJOR < 3
-
## Generate scope:
scope = ActsAsTaggableOn::Tag.scoped(:select => "#{ActsAsTaggableOn::Tag.table_name}.*, COUNT(*) AS count").order(options[:order]).limit(options[:limit])
@@ -104,17 +103,19 @@ def all_tag_counts(options = {})
at_most = sanitize_sql(['COUNT(*) <= ?', options.delete(:at_most)]) if options[:at_most]
having = [at_least, at_most].compact.join(' AND ')
+ group_columns = ActsAsTaggableOn::Tag.using_postgresql? ? grouped_column_names_for(ActsAsTaggableOn::Tag) : "#{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key}"
+
if ActiveRecord::VERSION::MAJOR >= 3
# Append the current scope to the scope, because we can't use scope(:find) in RoR 3.0 anymore:
scoped_select = "#{table_name}.#{primary_key}"
scope = scope.where("#{ActsAsTaggableOn::Tagging.table_name}.taggable_id IN(#{select(scoped_select).to_sql})")
# We have having() in RoR 3.0 so use it:
having = having.blank? ? "COUNT(*) > 0" : "COUNT(*) > 0 AND #{having}"
- scope = scope.group(grouped_column_names_for(ActsAsTaggableOn::Tag)).having(having)
+ scope = scope.group(group_columns).having(having)
else
# Having is not available in 2.3.x:
- group_by = "#{grouped_column_names_for(ActsAsTaggableOn::Tag)} HAVING COUNT(*) > 0"
+ group_by = "#{group_columns} HAVING COUNT(*) > 0"
group_by << " AND #{having}" unless having.blank?
scope = scope.group(group_by)
end
@@ -110,7 +110,9 @@ def tagged_with(tags, options = {})
" ON #{taggings_alias}.taggable_id = #{table_name}.#{primary_key}" +
" AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name)}"
- group = "#{grouped_column_names_for(self)} HAVING COUNT(#{taggings_alias}.taggable_id) = #{tags.size}"
+
+ group_columns = ActsAsTaggableOn::Tag.using_postgresql? ? grouped_column_names_for(self) : "#{table_name}.#{primary_key}"
+ group = "#{group_columns} HAVING COUNT(#{taggings_alias}.taggable_id) = #{tags.size}"
end
@@ -176,8 +178,17 @@ def all_tags_on(context)
tag_table_name = ActsAsTaggableOn::Tag.table_name
tagging_table_name = ActsAsTaggableOn::Tagging.table_name
- opts = ["#{tagging_table_name}.context = ?", context.to_s]
- base_tags.where(opts).order("max(#{tagging_table_name}.created_at)").group("#{tag_table_name}.id, #{tag_table_name}.name").all
+ opts = ["#{tagging_table_name}.context = ?", context.to_s]
+ scope = base_tags.where(opts)
+
+ if ActsAsTaggableOn::Tag.using_postgresql?
+ group_columns = grouped_column_names_for(ActsAsTaggableOn::Tag)
+ scope = scope.order("max(#{tagging_table_name}.created_at)").group(group_columns)
+ else
+ scope = scope.group("#{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key}")
+ end
+
+ scope.all
end
##
@@ -42,10 +42,12 @@ def matching_contexts_for(search_context, result_context, klass, options = {})
exclude_self = "#{klass.table_name}.id != #{id} AND" if self.class == klass
+ group_columns = ActsAsTaggableOn::Tag.using_postgresql? ? grouped_column_names_for(klass) : "#{klass.table_name}.#{klass.primary_key}"
+
klass.scoped({ :select => "#{klass.table_name}.*, COUNT(#{ActsAsTaggableOn::Tag.table_name}.id) AS count",
:from => "#{klass.table_name}, #{ActsAsTaggableOn::Tag.table_name}, #{ActsAsTaggableOn::Tagging.table_name}",
:conditions => ["#{exclude_self} #{klass.table_name}.id = #{ActsAsTaggableOn::Tagging.table_name}.taggable_id AND #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = '#{klass.to_s}' AND #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.id AND #{ActsAsTaggableOn::Tag.table_name}.name IN (?) AND #{ActsAsTaggableOn::Tagging.table_name}.context = ?", tags_to_find, result_context],
- :group => grouped_column_names_for(klass),
+ :group => group_columns,
:order => "count DESC" }.update(options))
end
@@ -54,10 +56,12 @@ def related_tags_for(context, klass, options = {})
exclude_self = "#{klass.table_name}.id != #{id} AND" if self.class == klass
+group_columns = ActsAsTaggableOn::Tag.using_postgresql? ? grouped_column_names_for(klass) : "#{klass.table_name}.#{klass.primary_key}"
+
klass.scoped({ :select => "#{klass.table_name}.*, COUNT(#{ActsAsTaggableOn::Tag.table_name}.id) AS count",
:from => "#{klass.table_name}, #{ActsAsTaggableOn::Tag.table_name}, #{ActsAsTaggableOn::Tagging.table_name}",
:conditions => ["#{exclude_self} #{klass.table_name}.id = #{ActsAsTaggableOn::Tagging.table_name}.taggable_id AND #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = '#{klass.to_s}' AND #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.id AND #{ActsAsTaggableOn::Tag.table_name}.name IN (?)", tags_to_find],
- :group => grouped_column_names_for(klass),
+ :group => group_columns,
:order => "count DESC" }.update(options))
end
end
@@ -14,6 +14,10 @@ class Tag < ::ActiveRecord::Base
validates_uniqueness_of :name
### SCOPES:
+
+ def self.using_postgresql?
+ connection.adapter_name == 'PostgreSQL'
+ end
def self.named(name)
where(["name #{like_operator} ?", name])
@@ -66,7 +70,7 @@ def count
class << self
private
def like_operator
- connection.adapter_name == 'PostgreSQL' ? 'ILIKE' : 'LIKE'
+ using_postgresql? ? 'ILIKE' : 'LIKE'
end
end

0 comments on commit c31c2e5

Please sign in to comment.