Class: Attributor::Collection

Inherits:
Object
  • Object
show all
Includes:
Container
Defined in:
lib/attributor/types/collection.rb

Direct Known Subclasses

CSV

Class Method Summary collapse

Methods included from Container

included

Class Method Details

.check_option!(name, definition) ⇒ Object



116
117
118
119
120
121
122
123
124
125
126
# File 'lib/attributor/types/collection.rb', line 116

def self.check_option!(name, definition)
  # TODO: support more options like :max_size
  case name
  when :reference
  when :member_options
  else
    return :unknown
  end

  :ok
end

.construct(constructor_block, options) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/attributor/types/collection.rb', line 98

def self.construct(constructor_block, options)

  member_options =  (options[:member_options]  || {} ).clone
  if options.has_key?(:reference) && !member_options.has_key?(:reference)
    member_options[:reference] = options[:reference]
  end

  # create the member_attribute, passing in our member_type and whatever constructor_block is.
  # that in turn will call construct on the type if applicable.
  @member_attribute = Attributor::Attribute.new self.member_type, member_options, &constructor_block

  # overwrite our type with whatever type comes out of the attribute
  @member_type = @member_attribute.type

  return self
end

.constructable?Boolean

Returns:



94
95
96
# File 'lib/attributor/types/collection.rb', line 94

def self.constructable? 
  true
end

.decode_string(value, context) ⇒ Object



76
77
78
# File 'lib/attributor/types/collection.rb', line 76

def self.decode_string(value,context)
  decode_json(value,context)
end

.describe(shallow = false) ⇒ Object



86
87
88
89
90
91
# File 'lib/attributor/types/collection.rb', line 86

def self.describe(shallow=false)
  hash = super(shallow)
  hash[:options] = {} unless hash[:options]
  hash[:member_attribute] = self.member_attribute.describe
  hash
end

.dump(values, **opts) ⇒ Object



81
82
83
84
# File 'lib/attributor/types/collection.rb', line 81

def self.dump(values, **opts)
  return nil if values.nil?
  values.collect { |value| member_attribute.dump(value,opts) }
end

.example(context = nil, options: {}) ⇒ Object

generates an example Collection

Returns:

  • An Array of native type objects conforming to the specified member_type



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/attributor/types/collection.rb', line 42

def self.example(context=nil, options: {})
  result = []
  size = options[:size] || (rand(3) + 1)
  size = [*size].sample if size.is_a?(Range)

  context ||= ["Collection-#{result.object_id}"]
  context = Array(context)

  size.times do |i|
    subcontext = context + ["at(#{i})"]
    result << self.member_attribute.example(subcontext)
  end

  result
end

.load(value, context = Attributor::DEFAULT_ROOT_CONTEXT, **options) ⇒ Object

The incoming value should be an array here, so the only decoding that we need to do is from the members (if there’s an :member_type defined option).



61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/attributor/types/collection.rb', line 61

def self.load(value,context=Attributor::DEFAULT_ROOT_CONTEXT, **options)
  if value.nil?
    return nil
  elsif value.is_a?(Enumerable)
    loaded_value = value
  elsif value.is_a?(::String)
    loaded_value = decode_string(value,context)
  else
    raise Attributor::IncompatibleTypeError, context: context, value_type: value.class, type: self
  end

  return loaded_value.collect { |member| self.member_attribute.load(member,context) }
end

.member_attributeObject



32
33
34
35
36
37
# File 'lib/attributor/types/collection.rb', line 32

def self.member_attribute
  @member_attribute ||= begin
    self.construct(nil,{})
    @member_attribute
  end
end

.member_typeObject



28
29
30
# File 'lib/attributor/types/collection.rb', line 28

def self.member_type
  @member_type ||= Attributor::Object
end

.native_typeObject



24
25
26
# File 'lib/attributor/types/collection.rb', line 24

def self.native_type
  return ::Array
end

.of(type) ⇒ Object

Returns anonymous class with specified type of collection members.

Examples:

Collection.of(Integer)

Parameters:

  • type (Attributor::Type)

    optional, defines the type of all collection members

Returns:

  • anonymous class with specified type of collection members



14
15
16
17
18
19
20
21
22
# File 'lib/attributor/types/collection.rb', line 14

def self.of(type)
  resolved_type = Attributor.resolve_type(type)
  unless resolved_type.ancestors.include?(Attributor::Type)
    raise Attributor::AttributorException.new("Collections can only have members that are Attributor::Types")
  end
  Class.new(self) do
    @member_type = resolved_type
  end
end

.validate(values, context = Attributor::DEFAULT_ROOT_CONTEXT, attribute = nil) ⇒ Object

Parameters:

  • values (Array)

    Array of values to validate



129
130
131
132
133
134
# File 'lib/attributor/types/collection.rb', line 129

def self.validate(values, context=Attributor::DEFAULT_ROOT_CONTEXT, attribute=nil)
  values.each_with_index.collect do |value, i|
    subcontext = context + ["at(#{i})"]
    self.member_attribute.validate(value, subcontext)
  end.flatten.compact
end

.validate_options(value, context, attribute) ⇒ Object



136
137
138
139
# File 'lib/attributor/types/collection.rb', line 136

def self.validate_options( value, context, attribute )
  errors = []
  errors
end