module ActsAsTaggableOn::Taggable::Cache

Public Class Methods

included(base) click to toggle source
# File lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb, line 3
def self.included(base)
  # When included, conditionally adds tag caching methods when the model
  #   has any "cached_#{tag_type}_list" column
  base.instance_eval do
    # @private
    def _has_tags_cache_columns?(db_columns)
      db_column_names = db_columns.map(&:name)
      tag_types.any? do |context|
        db_column_names.include?("cached_#{context.to_s.singularize}_list")
      end
    end

    # @private
    def _add_tags_caching_methods
      send :include, ActsAsTaggableOn::Taggable::Cache::InstanceMethods
      extend ActsAsTaggableOn::Taggable::Cache::ClassMethods

      before_save :save_cached_tag_list

      initialize_tags_cache
    end

    # ActiveRecord::Base.columns makes a database connection and caches the
    #   calculated columns hash for the record as @columns.  Since we don't
    #   want to add caching methods until we confirm the presence of a
    #   caching column, and we don't want to force opening a database
    #   connection when the class is loaded, here we intercept and cache
    #   the call to :columns as @acts_as_taggable_on_cache_columns
    #   to mimic the underlying behavior.  While processing this first
    #   call to columns, we do the caching column check and dynamically add
    #   the class and instance methods
    #   FIXME: this method cannot compile in rubinius
    def columns
      @acts_as_taggable_on_cache_columns ||= begin
        db_columns = super
        _add_tags_caching_methods if _has_tags_cache_columns?(db_columns)
        db_columns
      end
    end

  end
end

Public Instance Methods

_add_tags_caching_methods() click to toggle source

@private

# File lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb, line 16
def _add_tags_caching_methods
  send :include, ActsAsTaggableOn::Taggable::Cache::InstanceMethods
  extend ActsAsTaggableOn::Taggable::Cache::ClassMethods

  before_save :save_cached_tag_list

  initialize_tags_cache
end
_has_tags_cache_columns?(db_columns) click to toggle source

@private

# File lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb, line 8
def _has_tags_cache_columns?(db_columns)
  db_column_names = db_columns.map(&:name)
  tag_types.any? do |context|
    db_column_names.include?("cached_#{context.to_s.singularize}_list")
  end
end
columns() click to toggle source

ActiveRecord::Base.columns makes a database connection and caches the

calculated columns hash for the record as @columns.  Since we don't
want to add caching methods until we confirm the presence of a
caching column, and we don't want to force opening a database
connection when the class is loaded, here we intercept and cache
the call to :columns as @acts_as_taggable_on_cache_columns
to mimic the underlying behavior.  While processing this first
call to columns, we do the caching column check and dynamically add
the class and instance methods
FIXME: this method cannot compile in rubinius
Calls superclass method
# File lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb, line 35
def columns
  @acts_as_taggable_on_cache_columns ||= begin
    db_columns = super
    _add_tags_caching_methods if _has_tags_cache_columns?(db_columns)
    db_columns
  end
end