Module: CachedAt::HasManyThroughAssociation

Defined in:
lib/cached_at/associations/has_many_through_association.rb

Instance Method Summary collapse

Instance Method Details

#touch_cached_at(timestamp, method) ⇒ Object



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
# File 'lib/cached_at/associations/has_many_through_association.rb', line 4

def touch_cached_at(timestamp, method)
  using_reflection = reflection.parent_reflection || reflection
  return unless using_reflection.options[:cached_at]

  if using_reflection.inverse_of.nil?
    puts "WARNING: cannot updated cached at for relationship: #{owner.class.name}.#{using_reflection.name}, inverse_of not set"
    return
  end
  
  cache_column = "#{using_reflection.inverse_of.name}_cached_at"
  ids = [owner.send(using_reflection.association_primary_key), owner.send("#{using_reflection.association_primary_key}_was")].compact.uniq

  
  arel_table = klass._reflections[using_reflection.inverse_of.options[:through].to_s].klass.arel_table
  query = klass.joins(using_reflection.inverse_of.options[:through])
  query = if using_reflection.is_a?(ActiveRecord::Reflection::HasAndBelongsToManyReflection)
    query.where(arel_table[using_reflection.foreign_key].in(ids))
  else
    query.where(arel_table[using_reflection.inverse_of.foreign_key].in(ids))
  end

  if loaded?
    target.each { |r| r.raw_write_attribute(cache_column, timestamp) }
  end
  
  query.update_all({ cache_column => timestamp })
  traverse_relationships(klass, options[:cached_at], query, cache_column, timestamp)
end

#touch_records_added_cached_at(records, timestamp) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/cached_at/associations/has_many_through_association.rb', line 33

def touch_records_added_cached_at(records, timestamp)
  return if owner.new_record? || records.empty?

  using_reflection = reflection.parent_reflection || reflection

  if using_reflection.options[:cached_at]

    if using_reflection.inverse_of.nil?
      puts "WARNING: cannot updated cached at for relationship: #{klass.name}.#{name}, inverse_of not set"
      return
    end

    cache_column = "#{using_reflection.inverse_of.name}_cached_at"
    ids = records.inject([]) { |a, o| a += [o.send(klass.primary_key), o.send("#{klass.primary_key}_was")] }.compact.uniq
    query = klass.where(klass.primary_key => ids)
    records.each { |r| r.raw_write_attribute(cache_column, timestamp) }
    query.update_all({ cache_column => timestamp })
    traverse_relationships(klass, using_reflection.options[:cached_at], query, cache_column, timestamp)
  end

  if using_reflection.inverse_of&.options.try(:[], :cached_at) || using_reflection.inverse_of&.parent_reflection&.options.try(:[], :cached_at)
    cache_column = "#{using_reflection.name}_cached_at"
    owner.update_column(cache_column, timestamp) unless owner.new_record?
  end
end

#touch_records_removed_cached_at(records, timestamp) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/cached_at/associations/has_many_through_association.rb', line 59

def touch_records_removed_cached_at(records, timestamp)
  return if records.empty?
  
  using_reflection = reflection.parent_reflection || reflection
  inverse_reflection = using_reflection.inverse_of&.parent_reflection || using_reflection.inverse_of
  
  if using_reflection.options[:cached_at]
    if inverse_reflection.nil?
      puts "WARNING: cannot updated cached at for relationship: #{klass.name}.#{name}, inverse_of not set"
      return
    end
    
    cache_column = "#{inverse_reflection.name}_cached_at"
    ids = records.inject([]) { |a, o| a += [o.send(klass.primary_key), o.send("#{klass.primary_key}_was")] }.compact.uniq
    query = klass.where(klass.primary_key => ids)
    records.each { |r| r.raw_write_attribute(cache_column, timestamp) }
    query.update_all({ cache_column => timestamp })
    traverse_relationships(klass, reflection.options[:cached_at], query, cache_column, timestamp)
  end
  
  if !inverse_reflection.nil? && inverse_reflection.options[:cached_at]
    cache_column = "#{using_reflection.name}_cached_at"
    owner.raw_write_attribute(cache_column, timestamp)
    ids = records.inject([]) { |a, o| a += [o.send(klass.primary_key), o.send("#{klass.primary_key}_was")] }.compact.uniq
    
    arel_table = if inverse_reflection.is_a?(ActiveRecord::Reflection::HasAndBelongsToManyReflection)
      inverse_reflection.klass.const_get(:"HABTM_#{using_reflection.name.to_s.camelize}").arel_table
    else
      using_reflection.inverse_of.klass._reflections[using_reflection.inverse_of.options[:through].to_s].klass.arel_table
    end
    query = nil
    if inverse_reflection.is_a?(ActiveRecord::Reflection::HasAndBelongsToManyReflection)
      query = using_reflection.inverse_of.klass.joins(inverse_reflection.inverse_of.options[:through])
      query = query.where(arel_table[inverse_reflection.foreign_key].in(ids))
    else
      query = using_reflection.inverse_of.klass.joins(using_reflection.inverse_of.options[:through])
      query = query.where(arel_table[using_reflection.foreign_key].in(ids))
    end
    
    query.update_all({ cache_column => timestamp })
    owner.raw_write_attribute(cache_column, timestamp)
    traverse_relationships(klass, reflection.options[:cached_at], query, cache_column, timestamp)
  end
end