Module: IdentityCache::ConfigurationDSL::ClassMethods

Defined in:
lib/identity_cache/configuration_dsl.rb

Instance Method Summary collapse

Instance Method Details

#cache_attribute(attribute, options = {}) ⇒ Object

Will cache a single attribute on its own blob, it will add a fetch_attribute_by_id (or the value of the by option).

Example:

class Product
 cache_attribute :quantity, :by => :name
 cache_attribute :quantity  :by => [:name, :vendor]
end

Parameters

attribute Symbol with the name of the attribute being cached

Options

  • by: Other attribute or attributes in the model to keep values indexed. Default is :id



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/identity_cache/configuration_dsl.rb', line 162

def cache_attribute(attribute, options = {})
  options[:by] ||= :id
  fields = Array(options[:by])

  self.cache_attributes.push [attribute, fields]

  field_list = fields.join("_and_")
  arg_list = (0...fields.size).collect { |i| "arg#{i}" }.join(',')

  self.instance_eval(<<-CODE, __FILE__, __LINE__ + 1)
    def fetch_#{attribute}_by_#{field_list}(#{arg_list})
      attribute_dynamic_fetcher(#{attribute.inspect}, #{fields.inspect}, [#{arg_list}])
    end
  CODE
end

#cache_has_many(association, options = {}) ⇒ Object

Will cache an association to the class including IdentityCache. The embed option, if set, will make IdentityCache keep the association values in the same cache entry as the parent.

Embedded associations are more effective in offloading database work, however they will increase the size of the cache entries and make the whole entry expire when any of the embedded members change.

Example:

class Product
 cached_has_many :options, :embed => false
 cached_has_many :orders
 cached_has_many :buyers, :inverse_name => 'line_item'
end

Parameters

association Name of the association being cached as a symbol

Options

  • embed: If set to true, will cause IdentityCache to keep the values for this association in the same cache entry as the parent, instead of its own.

  • inverse_name: The name of the parent in the association if the name is not the lowercase pluralization of the parent object’s class



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/identity_cache/configuration_dsl.rb', line 96

def cache_has_many(association, options = {})
  options[:embed] = :ids unless options.has_key?(:embed)
  deprecate_embed_option(options, false, :ids)
  options[:inverse_name] ||= self.name.underscore.to_sym
  raise InverseAssociationError unless self.reflect_on_association(association)
  self.cached_has_manys[association] = options

  case options[:embed]
  when true
    build_recursive_association_cache(association, options)
  when :ids
    build_id_embedded_has_many_cache(association, options)
  else
    raise NotImplementedError
  end
end

#cache_has_one(association, options = {}) ⇒ Object

Will cache an association to the class including IdentityCache. IdentityCache will keep the association values in the same cache entry as the parent.

Example:

class Product
 cached_has_one :store, :embed => true
 cached_has_one :vendor
end

Parameters

association Symbol with the name of the association being cached

Options

  • embed: Only true is supported, which is also the default, so IdentityCache will keep the values for this association in the same cache entry as the parent, instead of its own.

  • inverse_name: The name of the parent in the association ( only necessary if the name is not the lowercase pluralization of the parent object’s class)



134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/identity_cache/configuration_dsl.rb', line 134

def cache_has_one(association, options = {})
  options[:embed] = true unless options.has_key?(:embed)
  options[:inverse_name] ||= self.name.underscore.to_sym
  raise InverseAssociationError unless self.reflect_on_association(association)
  self.cached_has_ones[association] = options

  if options[:embed] == true
    build_recursive_association_cache(association, options)
  else
    raise NotImplementedError
  end
end

#cache_index(*fields) ⇒ Object

Declares a new index in the cache for the class where IdentityCache was included.

IdentityCache will add a fetch_by_field1_and_field2_and_…field for every index.

Example:

class Product
  include IdentityCache
  cache_index :name, :vendor
end

Will add Product.fetch_by_name_and_vendor

Parameters

fields Array of symbols or strings representing the fields in the index

Options

  • unique: if the index would only have unique values

Raises:

  • (NotImplementedError)


42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/identity_cache/configuration_dsl.rb', line 42

def cache_index(*fields)
  raise NotImplementedError, "Cache indexes need an enabled primary index" unless primary_cache_index_enabled
  options = fields.extract_options!
  self.cache_indexes.push fields

  field_list = fields.join("_and_")
  arg_list = (0...fields.size).collect { |i| "arg#{i}" }.join(',')

  if options[:unique]
    self.instance_eval(ruby = <<-CODE, __FILE__, __LINE__ + 1)
      def fetch_by_#{field_list}(#{arg_list})
        identity_cache_single_value_dynamic_fetcher(#{fields.inspect}, [#{arg_list}])
      end

      # exception throwing variant
      def fetch_by_#{field_list}!(#{arg_list})
        fetch_by_#{field_list}(#{arg_list}) or raise ActiveRecord::RecordNotFound
      end
    CODE
  else
    self.instance_eval(ruby = <<-CODE, __FILE__, __LINE__ + 1)
      def fetch_by_#{field_list}(#{arg_list})
        identity_cache_multiple_value_dynamic_fetcher(#{fields.inspect}, [#{arg_list}])
      end
    CODE
  end
end

#disable_primary_cache_indexObject

Raises:

  • (NotImplementedError)


178
179
180
181
# File 'lib/identity_cache/configuration_dsl.rb', line 178

def disable_primary_cache_index
  raise NotImplementedError, "Secondary indexes rely on the primary index to function. You must either remove the secondary indexes or don't disable the primary" if self.cache_indexes.size > 0
  self.primary_cache_index_enabled = false
end