Class: IdentityCache::Cached::Reference::HasOne

Inherits:
Association
  • Object
show all
Defined in:
lib/identity_cache/cached/reference/has_one.rb

Overview

:nodoc:

Instance Attribute Summary collapse

Attributes inherited from Association

#cached_accessor_name, #name, #records_variable_name, #reflection

Instance Method Summary collapse

Methods inherited from Association

#embedded?, #embedded_by_reference?, #embedded_recursively?, #inverse_name, #validate

Constructor Details

#initialize(name, reflection:) ⇒ HasOne

Returns a new instance of HasOne.



7
8
9
10
11
# File 'lib/identity_cache/cached/reference/has_one.rb', line 7

def initialize(name, reflection:)
  super
  @cached_id_name = "fetch_#{id_name}"
  @id_variable_name = :"@#{id_cached_reader_name}"
end

Instance Attribute Details

#cached_id_nameObject (readonly)

Returns the value of attribute cached_id_name.



13
14
15
# File 'lib/identity_cache/cached/reference/has_one.rb', line 13

def cached_id_name
  @cached_id_name
end

#id_variable_nameObject (readonly)

Returns the value of attribute id_variable_name.



13
14
15
# File 'lib/identity_cache/cached/reference/has_one.rb', line 13

def id_variable_name
  @id_variable_name
end

Instance Method Details

#buildObject



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/identity_cache/cached/reference/has_one.rb', line 15

def build
  reflection.active_record.class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
    attr_reader :#{id_cached_reader_name}

    def #{cached_id_name}
      return #{id_variable_name} if defined?(#{id_variable_name})
      #{id_variable_name} = association(:#{name}).scope.ids.first
    end

    def #{cached_accessor_name}
      assoc = association(:#{name})
      if assoc.klass.should_use_cache? && !assoc.loaded?
        #{records_variable_name} ||= #{reflection.class_name}.fetch(#{cached_id_name}) if #{cached_id_name}
      else
        #{name}
      end
    end
  RUBY

  ParentModelExpiration.add_parent_expiry_hook(self)
end

#clear(record) ⇒ Object



45
46
47
48
49
50
51
# File 'lib/identity_cache/cached/reference/has_one.rb', line 45

def clear(record)
  [id_variable_name, records_variable_name].each do |ivar|
    if record.instance_variable_defined?(ivar)
      record.remove_instance_variable(ivar)
    end
  end
end

#fetch(records) ⇒ Object



53
54
55
# File 'lib/identity_cache/cached/reference/has_one.rb', line 53

def fetch(records)
  fetch_async(LoadStrategy::Eager, records) { |child_records| child_records }
end

#fetch_async(load_strategy, records) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/identity_cache/cached/reference/has_one.rb', line 57

def fetch_async(load_strategy, records)
  fetch_embedded_async(load_strategy, records) do
    ids_to_parent_record = records.each_with_object({}) do |record, hash|
      child_id = record.send(cached_id_name)
      hash[child_id] = record if child_id
    end

    load_strategy.load_multi(
      reflection.klass.cached_primary_index,
      ids_to_parent_record.keys
    ) do |child_records_by_id|
      parent_record_to_child_record = {}

      child_records_by_id.each do |id, child_record|
        parent_record = ids_to_parent_record.fetch(id)
        parent_record_to_child_record[parent_record] ||= child_record
      end

      parent_record_to_child_record.each do |parent, child|
        parent.instance_variable_set(records_variable_name, child)
      end

      yield child_records_by_id.values.compact
    end
  end
end

#read(record) ⇒ Object



37
38
39
# File 'lib/identity_cache/cached/reference/has_one.rb', line 37

def read(record)
  record.public_send(cached_id_name)
end

#write(record, id) ⇒ Object



41
42
43
# File 'lib/identity_cache/cached/reference/has_one.rb', line 41

def write(record, id)
  record.instance_variable_set(id_variable_name, id)
end