Class: ATDIS::Model
- Inherits:
-
Object
- Object
- ATDIS::Model
- Includes:
- TypeCastAttributes, Validators, ActiveModel::AttributeMethods, ActiveModel::Validations
- Defined in:
- lib/atdis/model.rb
Direct Known Subclasses
ATDIS::Models::Address, ATDIS::Models::Application, ATDIS::Models::Authority, ATDIS::Models::Document, ATDIS::Models::Event, ATDIS::Models::Info, ATDIS::Models::LandTitleRef, ATDIS::Models::Location, ATDIS::Models::Page, ATDIS::Models::Pagination, ATDIS::Models::Person, ATDIS::Models::Reference, ATDIS::Models::Response, ATDIS::Models::TorrensTitle
Instance Attribute Summary collapse
-
#attributes ⇒ Object
readonly
Returns the value of attribute attributes.
-
#attributes_before_type_cast ⇒ Object
readonly
Returns the value of attribute attributes_before_type_cast.
-
#json_left_overs ⇒ Object
Stores any part of the json that could not be interpreted.
-
#json_load_error ⇒ Object
Stores any part of the json that could not be interpreted.
-
#timezone ⇒ Object
readonly
Returns the value of attribute timezone.
-
#url ⇒ Object
Returns the value of attribute url.
Class Method Summary collapse
- .attribute_keys ⇒ Object
-
.attribute_names ⇒ Object
Does what the equivalent on Activerecord does.
- .cast(value, type, timezone) ⇒ Object
-
.cast_datetime(value, timezone) ⇒ Object
If timezone is given in the string then the datetime is read in using the timezone in the string and then converted to the timezone “zone” If the timezone isn’t given in the string then the datetime is read in using the timezone in “zone”.
- .cast_geojson(value) ⇒ Object
-
.cast_integer(value) ⇒ Object
This casting allows nil values.
- .cast_string(value) ⇒ Object
- .cast_uri(value) ⇒ Object
-
.hash_symbols_to_string(hash) ⇒ Object
Converts {bar: “yes”} to => {“bar” => “yes”}.
- .interpret(data, timezone) ⇒ Object
-
.partition_by_used(data) ⇒ Object
Partition the data into used and unused by returning [used, unused].
- .read_json(text, timezone) ⇒ Object
- .read_url(url, timezone) ⇒ Object
Instance Method Summary collapse
-
#initialize(params, timezone) ⇒ Model
constructor
A new instance of Model.
- #json_errors ⇒ Object
- #json_errors_in_children ⇒ Object
- #json_errors_local ⇒ Object
- #json_left_overs_is_empty ⇒ Object
- #json_loaded_correctly! ⇒ Object
-
#used_attribute?(attribute) ⇒ Boolean
Have we tried to use this attribute?.
Constructor Details
#initialize(params, timezone) ⇒ Model
Returns a new instance of Model.
153 154 155 156 157 158 159 160 161 162 |
# File 'lib/atdis/model.rb', line 153 def initialize(params, timezone) @timezone = timezone @attributes = {} @attributes_before_type_cast = {} return unless params params.each do |attr, value| send("#{attr}=", value) end end |
Instance Attribute Details
#attributes ⇒ Object (readonly)
Returns the value of attribute attributes.
48 49 50 |
# File 'lib/atdis/model.rb', line 48 def attributes @attributes end |
#attributes_before_type_cast ⇒ Object (readonly)
Returns the value of attribute attributes_before_type_cast.
48 49 50 |
# File 'lib/atdis/model.rb', line 48 def attributes_before_type_cast @attributes_before_type_cast end |
#json_left_overs ⇒ Object
Stores any part of the json that could not be interpreted. Usually signals an error if it isn’t empty.
51 52 53 |
# File 'lib/atdis/model.rb', line 51 def json_left_overs @json_left_overs end |
#json_load_error ⇒ Object
Stores any part of the json that could not be interpreted. Usually signals an error if it isn’t empty.
51 52 53 |
# File 'lib/atdis/model.rb', line 51 def json_load_error @json_load_error end |
#timezone ⇒ Object (readonly)
Returns the value of attribute timezone.
48 49 50 |
# File 'lib/atdis/model.rb', line 48 def timezone @timezone end |
#url ⇒ Object
Returns the value of attribute url.
52 53 54 |
# File 'lib/atdis/model.rb', line 52 def url @url end |
Class Method Details
.attribute_keys ⇒ Object
164 165 166 |
# File 'lib/atdis/model.rb', line 164 def self.attribute_keys attribute_types.keys end |
.attribute_names ⇒ Object
Does what the equivalent on Activerecord does
169 170 171 |
# File 'lib/atdis/model.rb', line 169 def self.attribute_names attribute_types.keys.map(&:to_s) end |
.cast(value, type, timezone) ⇒ Object
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/atdis/model.rb', line 173 def self.cast(value, type, timezone) # If it's already the correct type (or nil) then we don't need to do anything if value.nil? || value.is_a?(type) value # Special handling for arrays. When we typecast arrays we actually # typecast each member of the array elsif value.is_a?(Array) value.map { |v| cast(v, type, timezone) } elsif type == DateTime cast_datetime(value, timezone) elsif type == URI cast_uri(value) elsif type == String cast_string(value) elsif type == Integer cast_integer(value) elsif type == RGeo::GeoJSON cast_geojson(value) # Otherwise try to use Type.interpret to do the typecasting elsif type.respond_to?(:interpret) type.interpret(value, timezone) if value else raise end end |
.cast_datetime(value, timezone) ⇒ Object
If timezone is given in the string then the datetime is read in using the timezone in the string and then converted to the timezone “zone” If the timezone isn’t given in the string then the datetime is read in using the timezone in “zone”
203 204 205 206 207 |
# File 'lib/atdis/model.rb', line 203 def self.cast_datetime(value, timezone) ActiveSupport::TimeZone.new(timezone).iso8601(value).to_datetime rescue ArgumentError, KeyError nil end |
.cast_geojson(value) ⇒ Object
224 225 226 |
# File 'lib/atdis/model.rb', line 224 def self.cast_geojson(value) RGeo::GeoJSON.decode(hash_symbols_to_string(value)) end |
.cast_integer(value) ⇒ Object
This casting allows nil values
220 221 222 |
# File 'lib/atdis/model.rb', line 220 def self.cast_integer(value) value&.to_i end |
.cast_string(value) ⇒ Object
215 216 217 |
# File 'lib/atdis/model.rb', line 215 def self.cast_string(value) value.to_s end |
.cast_uri(value) ⇒ Object
209 210 211 212 213 |
# File 'lib/atdis/model.rb', line 209 def self.cast_uri(value) URI.parse(value) rescue URI::InvalidURIError nil end |
.hash_symbols_to_string(hash) ⇒ Object
Converts {bar: “yes”} to => {“bar” => “yes”}
229 230 231 232 233 234 235 236 237 238 239 |
# File 'lib/atdis/model.rb', line 229 def self.hash_symbols_to_string(hash) if hash.respond_to?(:each_pair) result = {} hash.each_pair do |key, value| result[key.to_s] = hash_symbols_to_string(value) end result else hash end end |
.interpret(data, timezone) ⇒ Object
90 91 92 93 |
# File 'lib/atdis/model.rb', line 90 def self.interpret(data, timezone) used, unused = partition_by_used(data) new(used.merge(json_left_overs: unused), timezone) end |
.partition_by_used(data) ⇒ Object
Partition the data into used and unused by returning [used, unused]
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/atdis/model.rb', line 58 def self.partition_by_used(data) used = {} unused = {} if data.respond_to?(:each) data.each do |key, value| if attribute_keys.include?(key) used[key] = value else unused[key] = value end end else unused = data end [used, unused] end |
.read_json(text, timezone) ⇒ Object
81 82 83 84 85 86 87 88 |
# File 'lib/atdis/model.rb', line 81 def self.read_json(text, timezone) data = MultiJson.load(text, symbolize_keys: true) interpret(data, timezone) rescue MultiJson::LoadError => e a = interpret({ response: [] }, timezone) a.json_load_error = e.to_s a end |
.read_url(url, timezone) ⇒ Object
75 76 77 78 79 |
# File 'lib/atdis/model.rb', line 75 def self.read_url(url, timezone) r = read_json(RestClient.get(url.to_s).to_str, timezone) r.url = url.to_s r end |
Instance Method Details
#json_errors ⇒ Object
134 135 136 |
# File 'lib/atdis/model.rb', line 134 def json_errors json_errors_local + json_errors_in_children end |
#json_errors_in_children ⇒ Object
120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/atdis/model.rb', line 120 def json_errors_in_children r = [] attributes.each do |attribute_as_string, value| attribute = attribute_as_string.to_sym if value.respond_to?(:json_errors) r += value.json_errors.map { |a, b| [{ attribute => a }, b] } elsif value.is_a?(Array) f = value.find { |v| v.respond_to?(:json_errors) && !v.json_errors.empty? } r += f.json_errors.map { |a, b| [{ attribute => [a] }, b] } if f end end r end |
#json_errors_local ⇒ Object
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/atdis/model.rb', line 101 def json_errors_local r = [] # First show special json error errors.keys.each do |attribute| r << [nil, errors[:json]] unless errors[:json].empty? # The :json attribute is special next if attribute == :json e = errors[attribute] next if e.empty? r << [ { attribute => attributes_before_type_cast[attribute.to_s] }, e.map { |m| ErrorMessage["#{attribute} #{m}", m.spec_section] } ] end r end |
#json_left_overs_is_empty ⇒ Object
143 144 145 146 147 148 149 150 151 |
# File 'lib/atdis/model.rb', line 143 def json_left_overs_is_empty return unless json_left_overs && !json_left_overs.empty? # We have extra parameters that shouldn't be there errors.add( :json, ErrorMessage["Unexpected parameters in json data: #{MultiJson.dump(json_left_overs)}", "4"] ) end |
#json_loaded_correctly! ⇒ Object
95 96 97 98 99 |
# File 'lib/atdis/model.rb', line 95 def json_loaded_correctly! return unless json_load_error errors.add(:json, ErrorMessage["Invalid JSON: #{json_load_error}", nil]) end |
#used_attribute?(attribute) ⇒ Boolean
Have we tried to use this attribute?
139 140 141 |
# File 'lib/atdis/model.rb', line 139 def used_attribute?(attribute) !attributes_before_type_cast[attribute].nil? end |