Skip to content

Commit

Permalink
Speed up acts-as-taggable-on by only including modules once
Browse files Browse the repository at this point in the history
  • Loading branch information
tomeric committed Mar 25, 2010
1 parent 2cae565 commit 16c4567
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 79 deletions.
16 changes: 8 additions & 8 deletions lib/acts_as_taggable_on/acts_as_taggable_on.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ def acts_as_taggable_on(*tag_types)
else
if ::ActiveRecord::VERSION::MAJOR < 3
include ActsAsTaggableOn::ActiveRecord::Backports
end
end

write_inheritable_attribute(:tag_types, tag_types)
class_inheritable_reader(:tag_types)

Expand All @@ -28,14 +28,14 @@ def acts_as_taggable_on(*tag_types)
def self.taggable?
true
end

include ActsAsTaggableOn::Taggable::Core
include ActsAsTaggableOn::Taggable::Collection
include ActsAsTaggableOn::Taggable::Cache
include ActsAsTaggableOn::Taggable::Ownership
include ActsAsTaggableOn::Taggable::Related
end
end

include ActsAsTaggableOn::Taggable::Core
include ActsAsTaggableOn::Taggable::Collection
include ActsAsTaggableOn::Taggable::Cache
include ActsAsTaggableOn::Taggable::Ownership
include ActsAsTaggableOn::Taggable::Related
end
end
end
23 changes: 16 additions & 7 deletions lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,25 @@ def self.included(base)
before_save :save_cached_tag_list
end

base.tag_types.map(&:to_s).each do |tag_type|
base.class_eval %(
def self.caching_#{tag_type.singularize}_list?
caching_tag_list_on?("#{tag_type}")
end
)
end
base.intialize_acts_as_taggable_on_cache
end

module ClassMethods
def intialize_acts_as_taggable_on_cache
tag_types.map(&:to_s).each do |tag_type|
class_eval %(
def self.caching_#{tag_type.singularize}_list?
caching_tag_list_on?("#{tag_type}")
end
)
end
end

def acts_as_taggable_on(*args)
super(*args)
intialize_acts_as_taggable_on_cache
end

def caching_tag_list_on?(context)
column_names.include?("cached_#{context.to_s.singularize}_list")
end
Expand Down
46 changes: 27 additions & 19 deletions lib/acts_as_taggable_on/acts_as_taggable_on/collection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,37 @@ module Collection
def self.included(base)
base.send :include, ActsAsTaggableOn::Taggable::Collection::InstanceMethods
base.extend ActsAsTaggableOn::Taggable::Collection::ClassMethods

base.tag_types.map(&:to_s).each do |tag_type|
base.class_eval %(
def self.#{tag_type.singularize}_counts(options={})
tag_counts_on('#{tag_type}', options)
end
base.initialize_acts_as_taggable_on_collection
end

module ClassMethods
def initialize_acts_as_taggable_on_collection
tag_types.map(&:to_s).each do |tag_type|
class_eval %(
def self.#{tag_type.singularize}_counts(options={})
tag_counts_on('#{tag_type}', options)
end
def #{tag_type.singularize}_counts(options = {})
tag_counts_on('#{tag_type}', options)
end
def #{tag_type.singularize}_counts(options = {})
tag_counts_on('#{tag_type}', options)
end
def top_#{tag_type}(limit = 10)
tag_counts_on('#{tag_type}', :order => 'count desc', :limit => limit.to_i)
end
def top_#{tag_type}(limit = 10)
tag_counts_on('#{tag_type}', :order => 'count desc', :limit => limit.to_i)
end
def self.top_#{tag_type}(limit = 10)
tag_counts_on('#{tag_type}', :order => 'count desc', :limit => limit.to_i)
end
)
def self.top_#{tag_type}(limit = 10)
tag_counts_on('#{tag_type}', :order => 'count desc', :limit => limit.to_i)
end
)
end
end
end

module ClassMethods

def acts_as_taggable_on(*args)
super(*args)
initialize_acts_as_taggable_on_collection
end

def tag_counts_on(context, options = {})
all_tag_counts(options.merge({:on => context.to_s}))
end
Expand Down
58 changes: 33 additions & 25 deletions lib/acts_as_taggable_on/acts_as_taggable_on/core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,45 @@ def self.included(base)

base.class_eval do
attr_writer :custom_contexts

after_save :save_tags
end

base.tag_types.map(&:to_s).each do |tag_type|
context_taggings = "#{tag_type.singularize}_taggings".to_sym
context_tags = tag_type.to_sym

base.class_eval do
has_many context_taggings, :as => :taggable, :dependent => :destroy, :include => :tag, :class_name => "Tagging",
:conditions => ['#{Tagging.table_name}.tagger_id IS NULL AND #{Tagging.table_name}.context = ?', tag_type]
has_many context_tags, :through => context_taggings, :source => :tag
end

base.class_eval %(
def #{tag_type.singularize}_list
tag_list_on('#{tag_type}')
end
def #{tag_type.singularize}_list=(new_tags)
set_tag_list_on('#{tag_type}', new_tags)
end
def all_#{tag_type}_list
all_tags_list_on('#{tag_type}')
end
)
end
base.initialize_acts_as_taggable_on_core
end

module ClassMethods
def initialize_acts_as_taggable_on_core
tag_types.map(&:to_s).each do |tag_type|
context_taggings = "#{tag_type.singularize}_taggings".to_sym
context_tags = tag_type.to_sym

class_eval do
has_many context_taggings, :as => :taggable, :dependent => :destroy, :include => :tag, :class_name => "Tagging",
:conditions => ['#{Tagging.table_name}.tagger_id IS NULL AND #{Tagging.table_name}.context = ?', tag_type]
has_many context_tags, :through => context_taggings, :source => :tag
end

class_eval %(
def #{tag_type.singularize}_list
tag_list_on('#{tag_type}')
end
def #{tag_type.singularize}_list=(new_tags)
set_tag_list_on('#{tag_type}', new_tags)
end
def all_#{tag_type}_list
all_tags_list_on('#{tag_type}')
end
)
end
end

def acts_as_taggable_on(*args)
super(*args)
initialize_acts_as_taggable_on_core
end

# all column names are necessary for PostgreSQL group clause
def grouped_column_names_for(object)
object.column_names.map { |column| "#{object.table_name}.#{column}" }.join(", ")
Expand Down
46 changes: 26 additions & 20 deletions lib/acts_as_taggable_on/acts_as_taggable_on/related.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,36 @@ module Related
def self.included(base)
base.send :include, ActsAsTaggableOn::Taggable::Related::InstanceMethods
base.extend ActsAsTaggableOn::Taggable::Related::ClassMethods

base.tag_types.map(&:to_s).each do |tag_type|
base.class_eval %(
def find_related_#{tag_type}(options = {})
related_tags_for('#{tag_type}', self.class, options)
end
alias_method :find_related_on_#{tag_type}, :find_related_#{tag_type}
end

module ClassMethods
def initialize_acts_as_taggable_on_related
tag_types.map(&:to_s).each do |tag_type|
class_eval %(
def find_related_#{tag_type}(options = {})
related_tags_for('#{tag_type}', self.class, options)
end
alias_method :find_related_on_#{tag_type}, :find_related_#{tag_type}
def find_related_#{tag_type}_for(klass, options = {})
related_tags_for('#{tag_type}', klass, options)
end
def find_related_#{tag_type}_for(klass, options = {})
related_tags_for('#{tag_type}', klass, options)
end
def find_matching_contexts(search_context, result_context, options = {})
matching_contexts_for(search_context.to_s, result_context.to_s, self.class, options)
end
def find_matching_contexts(search_context, result_context, options = {})
matching_contexts_for(search_context.to_s, result_context.to_s, self.class, options)
end
def find_matching_contexts_for(klass, search_context, result_context, options = {})
matching_contexts_for(search_context.to_s, result_context.to_s, klass, options)
end
)
def find_matching_contexts_for(klass, search_context, result_context, options = {})
matching_contexts_for(search_context.to_s, result_context.to_s, klass, options)
end
)
end
end

def acts_as_taggable_on(*args)
super(*args)
initialize_acts_as_taggable_on_related
end
end

module ClassMethods
end

module InstanceMethods
Expand Down

0 comments on commit 16c4567

Please sign in to comment.