Module: IdentityCache::QueryAPI::ClassMethods

Defined in:
lib/identity_cache/query_api.rb

Instance Method Summary collapse

Instance Method Details

#exists_with_identity_cache?(id) ⇒ Boolean

Similar to ActiveRecord::Base#exists? will return true if the id can be found in the cache or in the DB.

Returns:

  • (Boolean)

Raises:

  • (NotImplementedError)


12
13
14
15
# File 'lib/identity_cache/query_api.rb', line 12

def exists_with_identity_cache?(id)
  raise NotImplementedError, "exists_with_identity_cache? needs the primary index enabled" unless primary_cache_index_enabled
  !!fetch_by_id(id)
end

#fetch(id, options = {}) ⇒ Object

Default fetcher added to the model on inclusion, it behaves like ActiveRecord::Base.find, will raise ActiveRecord::RecordNotFound exception if id is not in the cache or the db.



42
43
44
# File 'lib/identity_cache/query_api.rb', line 42

def fetch(id, options={})
  fetch_by_id(id, options) or raise(ActiveRecord::RecordNotFound, "Couldn't find #{self.name} with ID=#{id}")
end

#fetch_by_id(id, options = {}) ⇒ Object

Default fetcher added to the model on inclusion, it behaves like ActiveRecord::Base.where(id: id).first

Raises:

  • (NotImplementedError)


19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/identity_cache/query_api.rb', line 19

def fetch_by_id(id, options={})
  ensure_base_model
  raise_if_scoped
  raise NotImplementedError, "fetching needs the primary index enabled" unless primary_cache_index_enabled
  return unless id
  record = if IdentityCache.should_use_cache?
    require_if_necessary do
      object = nil
      coder = IdentityCache.fetch(rails_cache_key(id)){ coder_from_record(object = resolve_cache_miss(id)) }
      object ||= record_from_coder(coder)
      IdentityCache.logger.error "[IDC id mismatch] fetch_by_id_requested=#{id} fetch_by_id_got=#{object.id} for #{object.inspect[(0..100)]} " if object && object.id != id.to_i
      object
    end
  else
    resolve_cache_miss(id)
  end
  prefetch_associations(options[:includes], [record]) if record && options[:includes]
  record
end

#fetch_multi(*ids) ⇒ Object

Default fetcher added to the model on inclusion, if behaves like ActiveRecord::Base.find_all_by_id

Raises:

  • (NotImplementedError)


48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/identity_cache/query_api.rb', line 48

def fetch_multi(*ids)
  ensure_base_model
  raise_if_scoped
  raise NotImplementedError, "fetching needs the primary index enabled" unless primary_cache_index_enabled
  options = ids.extract_options!
  ids.flatten!(1)
  records = if IdentityCache.should_use_cache?
    require_if_necessary do
      cache_keys = ids.map {|id| rails_cache_key(id) }
      key_to_id_map = Hash[ cache_keys.zip(ids) ]
      key_to_record_map = {}

      coders_by_key = IdentityCache.fetch_multi(cache_keys) do |unresolved_keys|
        ids = unresolved_keys.map {|key| key_to_id_map[key] }
        records = find_batch(ids)
        key_to_record_map = records.compact.index_by{ |record| rails_cache_key(record.id) }
        records.map {|record| coder_from_record(record) }
      end

      cache_keys.map{ |key| key_to_record_map[key] || record_from_coder(coders_by_key[key]) }
    end
  else
    find_batch(ids)
  end
  records.compact!
  prefetch_associations(options[:includes], records) if options[:includes]
  records
end