Module: ActsAsTaggableOn::Taggable::Cache

Defined in:
lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb

Defined Under Namespace

Modules: ClassMethods, InstanceMethods

Class Method Summary collapse

Class Method Details

.included(base) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 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
    def columns
      @acts_as_taggable_on_cache_columns ||= begin
        db_columns = super
        if _has_tags_cache_columns?(db_columns)
          _add_tags_caching_methods
        end
        db_columns
      end
    end

  end
end