Class: RedisMemo::MemoizeQuery::Invalidation
- Inherits:
-
Object
- Object
- RedisMemo::MemoizeQuery::Invalidation
- Defined in:
- lib/redis_memo/memoize_query/invalidation.rb
Overview
Automatically invalidate memoizable when modifying ActiveRecords objects. You still need to invalidate memos when you are using SQL queries to perform update / delete (does not trigger record callbacks)
Class Method Summary collapse
- .install(model_class) ⇒ Object
- .invalidate_new_records(model_class, &blk) ⇒ Object
- .invalidate_records_by_conflict_target(model_class, records:, conflict_target: nil, &blk) ⇒ Object
Class Method Details
.install(model_class) ⇒ Object
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 46 47 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 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/redis_memo/memoize_query/invalidation.rb', line 9 def self.install(model_class) var_name = :@@__redis_memo_memoize_query_invalidation_installed__ return if model_class.class_variable_defined?(var_name) model_class.class_eval do # A memory-persistent memoizable used for invalidating all queries of a # particular model def self.redis_memo_class_memoizable @redis_memo_class_memoizable ||= RedisMemo::MemoizeQuery.create_memo(self) end %i(delete decrement! increment!).each do |method_name| alias_method :"without_redis_memo_invalidation_#{method_name}", method_name define_method method_name do |*args| result = send(:"without_redis_memo_invalidation_#{method_name}", *args) RedisMemo::MemoizeQuery.invalidate(self) result end end end # Methods that won't trigger model callbacks # https://guides.rubyonrails.org/active_record_callbacks.html#skipping-callbacks %i( decrement_counter delete_all delete_by increment_counter touch_all update_column update_columns update_all update_counters ).each do |method_name| # Example: Model.update_all rewrite_default_method( model_class, model_class, method_name, class_method: true, ) # Example: Model.where(...).update_all rewrite_default_method( model_class, model_class.const_get(:ActiveRecord_Relation), method_name, class_method: false, ) end %i( insert insert! insert_all insert_all! ).each do |method_name| rewrite_insert_method( model_class, method_name, ) end %i( upsert upsert_all ).each do |method_name| rewrite_upsert_method( model_class, method_name, ) end %i( import import! ).each do |method_name| rewrite_import_method( model_class, method_name, ) end model_class.class_variable_set(var_name, true) end |
.invalidate_new_records(model_class, &blk) ⇒ Object
89 90 91 92 93 94 95 |
# File 'lib/redis_memo/memoize_query/invalidation.rb', line 89 def self.invalidate_new_records(model_class, &blk) current_id = model_class.maximum(model_class.primary_key) result = blk.call records = select_by_new_ids(model_class, current_id) RedisMemo::MemoizeQuery.invalidate(*records) unless records.empty? result end |
.invalidate_records_by_conflict_target(model_class, records:, conflict_target: nil, &blk) ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/redis_memo/memoize_query/invalidation.rb', line 97 def self.invalidate_records_by_conflict_target(model_class, records:, conflict_target: nil, &blk) if conflict_target.nil? # When the conflict_target is not set, we are basically inserting new # records since duplicate rows are simply skipped return invalidate_new_records(model_class, &blk) end relation = build_relation_by_conflict_target(model_class, records, conflict_target) # Invalidate records before updating records = select_by_conflict_target_relation(model_class, relation) RedisMemo::MemoizeQuery.invalidate(*records) unless records.empty? # Perform updating result = blk.call # Invalidate records after updating records = select_by_conflict_target_relation(model_class, relation) RedisMemo::MemoizeQuery.invalidate(*records) unless records.empty? result end |