Class: Attributor::Collection
- Inherits:
-
Array
- Object
- Array
- Attributor::Collection
- Defined in:
- lib/attributor/types/collection.rb
Direct Known Subclasses
Class Method Summary collapse
- .check_option!(name, definition) ⇒ Object
- .construct(constructor_block, options) ⇒ Object
- .constructable? ⇒ Boolean
- .decode_string(value, context) ⇒ Object
- .describe(shallow = false, example: nil) ⇒ Object
- .dump(values, **opts) ⇒ Object
-
.example(context = nil, options: {}) ⇒ Object
generates an example Collection.
- .family ⇒ Object
- .inherited(klass) ⇒ Object
-
.load(value, context = Attributor::DEFAULT_ROOT_CONTEXT, **options) ⇒ Object
The incoming value should be array-like here, so the only decoding that we need to do is from the members (if there’s an :member_type defined option).
- .member_attribute ⇒ Object
- .member_type ⇒ Object
- .native_type ⇒ Object
-
.of(type) ⇒ Object
Anonymous class with specified type of collection members.
- .options ⇒ Object
- .valid_type?(type) ⇒ Boolean
- .validate(object, context = Attributor::DEFAULT_ROOT_CONTEXT, attribute = nil) ⇒ Object
- .validate_options(value, context, attribute) ⇒ Object
Instance Method Summary collapse
Methods included from Container
Class Method Details
.check_option!(name, definition) ⇒ Object
146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/attributor/types/collection.rb', line 146 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
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/attributor/types/collection.rb', line 129 def self.construct(constructor_block, ) = ([:member_options] || {} ).clone if .has_key?(:reference) && !.has_key?(:reference) [:reference] = [: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, , &constructor_block # overwrite our type with whatever type comes out of the attribute @member_type = @member_attribute.type return self end |
.constructable? ⇒ Boolean
124 125 126 |
# File 'lib/attributor/types/collection.rb', line 124 def self.constructable? true end |
.decode_string(value, context) ⇒ Object
105 106 107 |
# File 'lib/attributor/types/collection.rb', line 105 def self.decode_string(value,context) decode_json(value,context) end |
.describe(shallow = false, example: nil) ⇒ Object
115 116 117 118 119 120 121 |
# File 'lib/attributor/types/collection.rb', line 115 def self.describe(shallow=false, example: nil) hash = super(shallow) hash[:options] = {} unless hash[:options] member_example = example.first if example hash[:member_attribute] = self.member_attribute.describe(true, example: member_example ) hash end |
.dump(values, **opts) ⇒ Object
110 111 112 113 |
# File 'lib/attributor/types/collection.rb', line 110 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
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/attributor/types/collection.rb', line 65 def self.example(context=nil, options: {}) result = [] size = [:size] || (rand(3) + 1) size = [*size].sample if size.is_a?(Range) context ||= ["Collection-#{result.object_id}"] context = Array(context) # avoid infinite recursion in example generation example_depth = context.size size = 0 if example_depth > Hash::MAX_EXAMPLE_DEPTH size.times do |i| subcontext = context + ["at(#{i})"] result << self.member_attribute.example(subcontext) end self.new(result) end |
.family ⇒ Object
46 47 48 |
# File 'lib/attributor/types/collection.rb', line 46 def self.family 'array' end |
.inherited(klass) ⇒ Object
27 28 29 30 31 |
# File 'lib/attributor/types/collection.rb', line 27 def self.inherited(klass) klass.instance_eval do @options = {} end end |
.load(value, context = Attributor::DEFAULT_ROOT_CONTEXT, **options) ⇒ Object
The incoming value should be array-like here, so the only decoding that we need to do is from the members (if there’s an :member_type defined option).
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/attributor/types/collection.rb', line 88 def self.load(value,context=Attributor::DEFAULT_ROOT_CONTEXT, **) if value.nil? return nil elsif value.is_a?(Enumerable) loaded_value = value elsif value.is_a?(::String) loaded_value = decode_string(value,context) elsif value.respond_to?(:to_a) loaded_value = value.to_a else raise Attributor::IncompatibleTypeError, context: context, value_type: value.class, type: self end self.new(loaded_value.collect { |member| self.member_attribute.load(member,context) }) end |
.member_attribute ⇒ Object
54 55 56 57 58 59 60 |
# File 'lib/attributor/types/collection.rb', line 54 def self.member_attribute @member_attribute ||= begin self.construct(nil,{}) @member_attribute end end |
.member_type ⇒ Object
50 51 52 |
# File 'lib/attributor/types/collection.rb', line 50 def self.member_type @member_type ||= Attributor::Object end |
.native_type ⇒ Object
38 39 40 |
# File 'lib/attributor/types/collection.rb', line 38 def self.native_type self end |
.of(type) ⇒ Object
Returns anonymous class with specified type of collection members.
15 16 17 18 19 20 21 22 23 |
# File 'lib/attributor/types/collection.rb', line 15 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 |
.options ⇒ Object
33 34 35 |
# File 'lib/attributor/types/collection.rb', line 33 def self. @options end |
.valid_type?(type) ⇒ Boolean
42 43 44 |
# File 'lib/attributor/types/collection.rb', line 42 def self.valid_type?(type) type.kind_of?(self) || type.kind_of?(::Enumerable) end |
.validate(object, context = Attributor::DEFAULT_ROOT_CONTEXT, attribute = nil) ⇒ Object
159 160 161 162 163 164 165 166 167 |
# File 'lib/attributor/types/collection.rb', line 159 def self.validate(object, context=Attributor::DEFAULT_ROOT_CONTEXT, attribute=nil) context = [context] if context.is_a? ::String unless object.kind_of?(self) raise ArgumentError, "#{self.name} can not validate object of type #{object.class.name} for #{Attributor.humanize_context(context)}." end object.validate(context) end |
.validate_options(value, context, attribute) ⇒ Object
169 170 171 172 |
# File 'lib/attributor/types/collection.rb', line 169 def self.( value, context, attribute ) errors = [] errors end |
Instance Method Details
#dump(**opts) ⇒ Object
183 184 185 |
# File 'lib/attributor/types/collection.rb', line 183 def dump(**opts) self.collect { |value| self.class.member_attribute.dump(value,opts) } end |
#validate(context = Attributor::DEFAULT_ROOT_CONTEXT) ⇒ Object
175 176 177 178 179 180 |
# File 'lib/attributor/types/collection.rb', line 175 def validate(context=Attributor::DEFAULT_ROOT_CONTEXT) self.each_with_index.collect do |value, i| subcontext = context + ["at(#{i})"] self.class.member_attribute.validate(value, subcontext) end.flatten.compact end |