Class: TranslationDiff::Stores::ActiveRecord

Inherits:
Object
  • Object
show all
Includes:
ActiveRecord::Support
Defined in:
lib/translation_diff/stores/active_record.rb

Overview

Caches translations in the application's own database; ActiveRecord is required on first use, never at load.

Constant Summary

Constants included from ActiveRecord::Support

ActiveRecord::Support::MINIMUM_ACTIVE_RECORD

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ActiveRecord::Support

#model

Constructor Details

#initialize(namespace:, ttl:, table_name:, base: nil, prune_probability: 0.0) ⇒ ActiveRecord

Returns a new instance of ActiveRecord.



11
12
13
14
15
16
17
# File 'lib/translation_diff/stores/active_record.rb', line 11

def initialize(namespace:, ttl:, table_name:, base: nil, prune_probability: 0.0)
  @namespace = namespace
  @ttl = ttl
  @table_name = table_name
  @base = base
  @prune_probability = prune_probability
end

Class Method Details

.build(config) ⇒ Object



5
6
7
8
9
# File 'lib/translation_diff/stores/active_record.rb', line 5

def self.build(config)
  new(namespace: config.cache_namespace, ttl: config.cache_ttl,
      table_name: config.cache_table_name, base: config.active_record_base,
      prune_probability: config.cache_prune_probability)
end

Instance Method Details

#prune ⇒ Object

Reads never serve an expired row; deleting one is this, and it is the host's call when to run it.



50
# File 'lib/translation_diff/stores/active_record.rb', line 50

def prune = model.where(namespace: @namespace).where(expires_at: ...Time.now.utc).delete_all

#read_multi(keys) ⇒ Object

One query, then the caller's order restored -- a missing or expired key is a nil in its own position.



20
21
22
23
24
25
26
# File 'lib/translation_diff/stores/active_record.rb', line 20

def read_multi(keys)
  return [] if keys.empty?

  digests = keys.map { |key| digest(key) }
  found = live.where(key_digest: digests).pluck(:key_digest, :translation).to_h
  digests.map { |d| found[d] }
end

#write(key, value) ⇒ Object



28
29
30
31
# File 'lib/translation_diff/stores/active_record.rb', line 28

def write(key, value)
  write_multi([[key, value]])
  value
end

#write_multi(pairs) ⇒ Object

One upsert for the whole batch; the unique index makes the second write of a key replace the first.



34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/translation_diff/stores/active_record.rb', line 34

def write_multi(pairs)
  return pairs if pairs.empty?

  # A savepoint, not the caller's own transaction: a failed write must not abort a transaction it does not own.
  model.transaction(requires_new: true) do
    model.upsert_all(pairs.to_h.map { |key, value| row(key, value) }, **upsert_options(model.connection))
  end
  prune_sometimes
  pairs
rescue StandardError => e
  raise unless ar_error?(e)

  raise redacted_error(e), cause: nil
end