Class: Alula::DcpResource
Overview
Parent class for all DCP objects
Direct Known Subclasses
Defined Under Namespace
Classes: ModelErrors
Instance Attribute Summary collapse
-
#device_id ⇒ Object
Returns the value of attribute device_id.
-
#dirty_attributes ⇒ Object
Returns the value of attribute dirty_attributes.
-
#errors ⇒ Object
Returns the value of attribute errors.
-
#meta ⇒ Object
Returns the value of attribute meta.
-
#rate_limit ⇒ Object
Returns the value of attribute rate_limit.
-
#raw_data ⇒ Object
Returns the value of attribute raw_data.
-
#values ⇒ Object
Returns the value of attribute values.
Class Method Summary collapse
-
.build(device_id) ⇒ Object
Construct a new resource, ready to receive attributes, with empty values for all attrs.
- .class_name ⇒ Object
- .discriminate_by(mapping = nil) ⇒ Object
- .discriminator(field_name = nil) ⇒ Object
Instance Method Summary collapse
- #annotate_errors(model_errors) ⇒ Object
-
#apply_attributes(attributes, merge_only: false) ⇒ Object
Take a hash of attributes and apply them to the model.
-
#as_json ⇒ Object
Fetch known attributes out of the object, collected into a Hash in camelCase format Intended for eventually making its way back up to the API.
-
#as_patchable_json ⇒ Object
Reduce as_json to a set that can be updated.
- #clone ⇒ Object
- #construct_from(device_id, json_object) ⇒ Object
- #errors? ⇒ Boolean
-
#filter_builder ⇒ Object
(also: #fb)
Return an instance of QueryEngine annotated with the correct model attributes.
- #find_value(key) ⇒ Object
-
#initialize(device_id, attributes = {}) ⇒ DcpResource
constructor
A new instance of DcpResource.
- #model_name ⇒ Object
- #pick_value_for_key(val, ruby_key) ⇒ Object
- #reconstruct_from(device_id, json_object) ⇒ Object
- #refresh ⇒ Object
Constructor Details
#initialize(device_id, attributes = {}) ⇒ DcpResource
Returns a new instance of DcpResource.
12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/alula/dcp_resource.rb', line 12 def initialize(device_id, attributes = {}) @raw_data = {} @dirty_attributes = Set.new @values = attributes @errors = ModelErrors.new(self.class) klass = get_discriminated_class(attributes) if klass != self.class klass.new(device_id, attributes) else construct_from(device_id, attributes) end end |
Instance Attribute Details
#device_id ⇒ Object
Returns the value of attribute device_id.
6 7 8 |
# File 'lib/alula/dcp_resource.rb', line 6 def device_id @device_id end |
#dirty_attributes ⇒ Object
Returns the value of attribute dirty_attributes.
6 7 8 |
# File 'lib/alula/dcp_resource.rb', line 6 def dirty_attributes @dirty_attributes end |
#errors ⇒ Object
Returns the value of attribute errors.
6 7 8 |
# File 'lib/alula/dcp_resource.rb', line 6 def errors @errors end |
#meta ⇒ Object
Returns the value of attribute meta.
6 7 8 |
# File 'lib/alula/dcp_resource.rb', line 6 def @meta end |
#rate_limit ⇒ Object
Returns the value of attribute rate_limit.
6 7 8 |
# File 'lib/alula/dcp_resource.rb', line 6 def rate_limit @rate_limit end |
#raw_data ⇒ Object
Returns the value of attribute raw_data.
6 7 8 |
# File 'lib/alula/dcp_resource.rb', line 6 def raw_data @raw_data end |
#values ⇒ Object
Returns the value of attribute values.
6 7 8 |
# File 'lib/alula/dcp_resource.rb', line 6 def values @values end |
Class Method Details
.build(device_id) ⇒ Object
Construct a new resource, ready to receive attributes, with empty values for all attrs. Useful for making New resources
33 34 35 36 37 |
# File 'lib/alula/dcp_resource.rb', line 33 def self.build(device_id) fields = get_fields.keys.map { |k| Util.camelize(k) } empty_shell = fields.each_with_object({}) { |f, obj| obj[f] = nil } new(device_id, empty_shell) end |
.class_name ⇒ Object
8 9 10 |
# File 'lib/alula/dcp_resource.rb', line 8 def self.class_name name.split('::')[-1] end |
.discriminate_by(mapping = nil) ⇒ Object
192 193 194 195 196 |
# File 'lib/alula/dcp_resource.rb', line 192 def discriminate_by(mapping = nil) return @discriminator_mapping unless mapping @discriminator_mapping = mapping end |
.discriminator(field_name = nil) ⇒ Object
186 187 188 189 190 |
# File 'lib/alula/dcp_resource.rb', line 186 def discriminator(field_name = nil) return @discriminator unless field_name @discriminator = field_name end |
Instance Method Details
#annotate_errors(model_errors) ⇒ Object
167 168 169 170 171 172 |
# File 'lib/alula/dcp_resource.rb', line 167 def annotate_errors(model_errors) @errors = ModelErrors.new(self.class) model_errors.each_pair do |field_name, error| errors.add(field_name, error) end end |
#apply_attributes(attributes, merge_only: false) ⇒ Object
Take a hash of attributes and apply them to the model
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/alula/dcp_resource.rb', line 52 def apply_attributes(attributes, merge_only: false) res = attributes.each do |key, value| json_key = Util.camelize(key.to_s) sym_key = key.to_sym opts = self.class.get_fields[sym_key] || self.class.get_fields[:primitive] if merge_only # merge the value into the existing value if value.is_a?(Array) value.each_index do |index| send(sym_key)[index].apply_attributes(value[index], merge_only: true) end elsif value.is_a?(Hash) && send(sym_key).respond_to?(:apply_attributes) send(sym_key).apply_attributes(value, merge_only: true) elsif value.is_a?(Hash) && send(sym_key).respond_to?(:each) send("#{key}=", value) elsif opts[:type] == :number @values[json_key] = value.to_i elsif opts[:type] == :boolean @values[json_key] = [true, 'true', 1, '1'].include?(value) else @values[json_key] = value end elsif self.class.has_svm send(:staged).send("#{key}=", value) if send(:staged).respond_to?(key) else send("#{key}=", value) end end return @values if merge_only res end |
#as_json ⇒ Object
Fetch known attributes out of the object, collected into a Hash in camelCase format Intended for eventually making its way back up to the API
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/alula/dcp_resource.rb', line 108 def as_json field_names.each_with_object({}) do |ruby_key, obj| key = Util.camelize(ruby_key) val = find_value(ruby_key) # we don't want to include nil values in the JSON (for now?) next if val.nil? # if the key is primitive and the class has svm, use staged as key if key == 'primitive' && self.class.has_svm key = 'staged' elsif self.class.has_svm && key != 'index' # if has_svm and not primitive field need to nest values inside 'staged' or 'value' # index is a special case, it's outside of staged/value obj['staged'] ||= {} obj['staged'][key] = pick_value_for_key(val, ruby_key) next end obj[key] = pick_value_for_key(val, ruby_key) end end |
#as_patchable_json ⇒ Object
Reduce as_json to a set that can be updated
160 161 162 163 164 165 |
# File 'lib/alula/dcp_resource.rb', line 160 def as_patchable_json values = as_json.each_pair.each_with_object({}) do |(key, val), collector| collector[key] = val end values.reject { |k, _v| %w[index version].include? k } # blacklist index and version end |
#clone ⇒ Object
25 26 27 |
# File 'lib/alula/dcp_resource.rb', line 25 def clone self.class.new(@device_id, @raw_data) end |
#construct_from(device_id, json_object) ⇒ Object
39 40 41 42 43 44 45 46 47 48 |
# File 'lib/alula/dcp_resource.rb', line 39 def construct_from(device_id, json_object) @raw_data = json_object.dup @values = json_object @meta = Alula::Dcp::Meta.new(@values['meta']) unless empty_value?(@values['meta']) self.device_id = device_id @errors = ModelErrors.new(self.class) self end |
#errors? ⇒ Boolean
89 90 91 |
# File 'lib/alula/dcp_resource.rb', line 89 def errors? @errors.any? end |
#filter_builder ⇒ Object Also known as: fb
Return an instance of QueryEngine annotated with the correct model attributes
176 177 178 |
# File 'lib/alula/dcp_resource.rb', line 176 def filter_builder Alula::FilterBuilder.new(self.class) end |
#find_value(key) ⇒ Object
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/alula/dcp_resource.rb', line 140 def find_value(key) # index is a special case, it's not in staged or value # must return early to avoid errors when staged/value are primitive type return send(key) if key == :index json_key = Util.camelize(key.to_s) return values[json_key] unless self.class.has_svm # prioritize dirty attributes, then staged, then value # ideally we should use only dirty attributes, done by executing .apply_attributes return @dirty_attributes[key] if @dirty_attributes.include?(key) # for primitive types we should just return staged or value return staged || value if key == :primitive return staged.send(key) if staged.respond_to?(key) value.send(key) if value.respond_to?(key) end |
#model_name ⇒ Object
181 182 183 |
# File 'lib/alula/dcp_resource.rb', line 181 def model_name self.class end |
#pick_value_for_key(val, ruby_key) ⇒ Object
130 131 132 133 134 135 136 137 138 |
# File 'lib/alula/dcp_resource.rb', line 130 def pick_value_for_key(val, ruby_key) if val.is_a? Array val.map { |v| parse_value(v, ruby_key) } elsif val.is_a?(Alula::Dcp::ObjectField) || val.is_a?(Alula::DcpResource) val.as_json else parse_value(val, ruby_key) end end |
#reconstruct_from(device_id, json_object) ⇒ Object
85 86 87 |
# File 'lib/alula/dcp_resource.rb', line 85 def reconstruct_from(device_id, json_object) construct_from(device_id, json_object) end |
#refresh ⇒ Object
93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/alula/dcp_resource.rb', line 93 def refresh response = Alula::Client.request(:get, resource_url, {}, {}) if response.ok? model = construct_from(device_id, response.data) model.rate_limit = response.rate_limit model else error_class = AlulaError.for_response(response) raise error_class end end |