Class: Common::Collection

Inherits:
Object
  • Object
show all
Extended by:
ActiveModel::Naming, Forwardable
Includes:
ActiveModel::Serialization
Defined in:
lib/common/models/collection.rb

Overview

Wrapper for collection to keep aggregates

Constant Summary collapse

CACHE_NAMESPACE =
'common_collection'
CACHE_DEFAULT_TTL =

default to 1 hour

3600
OPERATIONS_MAP =
{
  'eq' => '==',
  'lteq' => '<=',
  'gteq' => '>=',
  'not_eq' => '!=',
  'match' => 'match'
}.with_indifferent_access.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(klass = Array, data: [], metadata: {}, errors: {}, cache_key: nil) ⇒ Collection

Returns a new instance of Collection.



33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/common/models/collection.rb', line 33

def initialize(klass = Array, data: [], metadata: {}, errors: {}, cache_key: nil)
  data = Array.wrap(data) # If data is passed in as nil, wrap it as an empty array
  @type = klass
  @attributes = data
  @metadata = 
  @errors = errors
  @cache_key = cache_key

  (@data = data) && return if defined?(::WillPaginate::Collection) && data.is_a?(WillPaginate::Collection)

  @data = data.collect do |element|
    element.is_a?(Hash) ? klass.new(element) : element
  end
end

Instance Attribute Details

#attributesObject (readonly) Also known as: to_h, to_hash

Returns the value of attribute attributes.



16
17
18
# File 'lib/common/models/collection.rb', line 16

def attributes
  @attributes
end

#dataObject Also known as: members

Returns the value of attribute data.



17
18
19
# File 'lib/common/models/collection.rb', line 17

def data
  @data
end

#errorsObject

Returns the value of attribute errors.



17
18
19
# File 'lib/common/models/collection.rb', line 17

def errors
  @errors
end

#metadataObject

Returns the value of attribute metadata.



17
18
19
# File 'lib/common/models/collection.rb', line 17

def 
  @metadata
end

#typeObject

Returns the value of attribute type.



17
18
19
# File 'lib/common/models/collection.rb', line 17

def type
  @type
end

Class Method Details

.bust(cache_keys) ⇒ Object



79
80
81
82
# File 'lib/common/models/collection.rb', line 79

def self.bust(cache_keys)
  cache_keys = Array.wrap(cache_keys)
  cache_keys.map { |cache_key| redis_namespace.del(cache_key) }
end

.cache(json_hash, cache_key, ttl) ⇒ Object



74
75
76
77
# File 'lib/common/models/collection.rb', line 74

def self.cache(json_hash, cache_key, ttl)
  redis_namespace.set(cache_key, json_hash)
  redis_namespace.expire(cache_key, ttl)
end

.fetch(klass, cache_key: nil, ttl: CACHE_DEFAULT_TTL) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/common/models/collection.rb', line 56

def self.fetch(klass, cache_key: nil, ttl: CACHE_DEFAULT_TTL)
  raise 'No Block Given' unless block_given?

  if cache_key
    json_string = redis_namespace.get(cache_key)
    if json_string.nil?
      collection = new(klass, **yield.merge(cache_key:))
      cache(collection.serialize, cache_key, ttl)
      collection
    else
      json_hash = Oj.load(json_string)
      new(klass, **json_hash.merge('cache_key' => cache_key).symbolize_keys)
    end
  else
    new(klass, **yield)
  end
end

.redis_namespaceObject



48
49
50
# File 'lib/common/models/collection.rb', line 48

def self.redis_namespace
  @redis_namespace ||= Redis::Namespace.new(CACHE_NAMESPACE, redis: $redis)
end

Instance Method Details

#bustObject



84
85
86
# File 'lib/common/models/collection.rb', line 84

def bust
  self.class.bust(@cache_key) if cached?
end

#cached?Boolean

Returns:

  • (Boolean)


88
89
90
# File 'lib/common/models/collection.rb', line 88

def cached?
  @cache_key.present?
end

#find_by(filter = {}) ⇒ Object



96
97
98
99
100
101
# File 'lib/common/models/collection.rb', line 96

def find_by(filter = {})
  verify_filter_keys!(filter)
  result = @data.select { |item| finder(item, filter) }
   = @metadata.merge(filter:)
  Collection.new(type, data: result, metadata:, errors:)
end

#find_first_by(filter = {}) ⇒ Object



103
104
105
106
107
108
109
110
# File 'lib/common/models/collection.rb', line 103

def find_first_by(filter = {})
  verify_filter_keys!(filter)
  result = @data.detect { |item| finder(item, filter) }
  return nil if result.nil?

  result. = 
  result
end

#paginate(page: nil, per_page: nil) ⇒ Object



124
125
126
127
128
129
130
# File 'lib/common/models/collection.rb', line 124

def paginate(page: nil, per_page: nil)
  page = page.try(:to_i) || 1
  max_per_page = type.max_per_page || 100
  per_page = [(per_page.try(:to_i) || type.per_page || 10), max_per_page].min
  collection = paginator(page, per_page)
  Collection.new(type, data: collection, metadata: .merge(pagination_meta(page, per_page)), errors:)
end

#redis_namespaceObject



52
53
54
# File 'lib/common/models/collection.rb', line 52

def redis_namespace
  @redis_namespace ||= self.class.redis_namespace
end

#serializeObject



132
133
134
# File 'lib/common/models/collection.rb', line 132

def serialize
  { data:, metadata:, errors: }.to_json
end

#sort(sort_params) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
# File 'lib/common/models/collection.rb', line 112

def sort(sort_params)
  fields = sort_fields(sort_params || type.default_sort)
  result = @data.sort_by do |item|
    fields.map do |k, v|
      v == 'ASC' ? Ascending.new(item.send(k)) : Descending.new(item.send(k))
    end
  end

   = @metadata.merge(sort: fields)
  Collection.new(type, data: result, metadata:, errors:)
end

#ttlObject



92
93
94
# File 'lib/common/models/collection.rb', line 92

def ttl
  @cache_key.present? ? redis_namespace.ttl(@cache_key) : nil
end