Class: Primalize::Many

Inherits:
Object
  • Object
show all
Defined in:
lib/primalize/many.rb

Defined Under Namespace

Classes: Enumerable, Optional

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attributes) ⇒ Many

Returns a new instance of Many.



91
92
93
94
95
# File 'lib/primalize/many.rb', line 91

def initialize attributes
  validate_attributes! attributes

  @attributes = attributes
end

Class Method Details

.add_attributes(attrs) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
# File 'lib/primalize/many.rb', line 12

def self.add_attributes attrs
  return if attrs.none?

  attrs.each do |attr, serializer_class|
    if serializer_class.nil?
      raise TypeError, "Serializer for #{self}##{attr} cannot be nil"
    end
  end

  @attributes.merge! attrs
end

.attributes(attrs = {}) ⇒ Object



5
6
7
8
9
10
# File 'lib/primalize/many.rb', line 5

def self.attributes attrs={}
  @attributes ||= {}
  add_attributes attrs

  @attributes
end

.enumerable(serializer_class) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/primalize/many.rb', line 29

def self.enumerable serializer_class
  Class.new(Enumerable) do
    define_method :call do
      @enumerable.map { |item| serializer_class.new(item).call }
    end

    define_singleton_method :inspect do
      "enumerable(#{serializer_class.inspect})"
    end

    define_singleton_method :attributes do
      serializer_class.attributes
    end
  end
end

.inherited(klass) ⇒ Object

Pass on our attributes to child classes



25
26
27
# File 'lib/primalize/many.rb', line 25

def self.inherited klass
  klass.attributes attributes
end

.inspectObject



83
84
85
86
87
88
89
# File 'lib/primalize/many.rb', line 83

def self.inspect
  attrs = attributes
    .map { |attr, serializer| "#{attr}: #{serializer.inspect}" }
    .join(', ')

  "#{name}(#{attrs})"
end

.optional(serializer_class) ⇒ Object



45
46
47
48
49
50
51
52
53
54
# File 'lib/primalize/many.rb', line 45

def self.optional serializer_class
  Class.new(Optional) do
    define_method :initialize do |object|
      return if object.nil?

      @object = object
      @serializer = serializer_class.new(object)
    end
  end
end

Instance Method Details

#callObject



117
118
119
120
121
# File 'lib/primalize/many.rb', line 117

def call
  self.class.attributes.each_with_object({}) do |(attr, serializer_class), hash|
    hash[attr] = serializer_class.new(@attributes.fetch(attr)).call
  end
end

#to_csv(attr) ⇒ Object



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/primalize/many.rb', line 127

def to_csv attr
  CSV.generate do |csv|
    result = call[attr]

    csv << self.class.attributes[attr].attributes.keys

    case result
    when Hash
      csv << result.values
    when Array
      result.each do |hash|
        csv << hash.values
      end
    end
  end
end

#to_jsonObject



123
124
125
# File 'lib/primalize/many.rb', line 123

def to_json
  call.to_json
end

#validate_attributes!(attributes) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/primalize/many.rb', line 97

def validate_attributes! attributes
  attr_map = self.class.attributes
  all_required_attributes_provided = attr_map
    .each_key
    .all? do |key|
      attributes[key] || (attr_map[key].superclass == Optional)
    end

  unless all_required_attributes_provided
    non_nil_keys = attributes
      .select { |_attr, value| value }
      .map { |attr, _value| attr }

    missing_keys = self.class.attributes.keys - non_nil_keys

    raise ArgumentError,
      "#{self.class} is missing the following keys: #{missing_keys.map(&:inspect).join(', ')}"
  end
end