Class: FHIR::Model
- Inherits:
-
Object
- Object
- FHIR::Model
- Extended by:
- Deprecate
- Defined in:
- lib/fhir_models/bootstrap/model.rb
Direct Known Subclasses
Instance Method Summary collapse
-
#==(other) ⇒ Object
(also: #eql?)
allow two FHIR models to be compared for equality.
- #attribute_mismatch(left, right, exclude = []) ⇒ Object
- #compare_attribute(left, right, exclude = []) ⇒ Object
- #each_element(path = nil, &block) ⇒ Object
- #equals?(other, exclude = []) ⇒ Boolean
-
#hash ⇒ Object
This is necessary for uniq to properly identify two FHIR models as being identical.
-
#initialize(hash = {}) ⇒ Model
constructor
A new instance of Model.
- #method_missing(method_name, *_args, &_block) ⇒ Object
- #mismatch(other, exclude = []) ⇒ Object
- #primitive?(datatype, value) ⇒ Boolean
- #respond_to_missing?(method_name) ⇒ Boolean
- #to_reference ⇒ Object
- #valid? ⇒ Boolean
- #validate(contained = nil) ⇒ Object
- #validate_profile(metadata, contained = nil) ⇒ Object
Methods included from Deprecate
Constructor Details
#initialize(hash = {}) ⇒ Model
Returns a new instance of Model.
10 11 12 13 14 15 16 17 18 19 |
# File 'lib/fhir_models/bootstrap/model.rb', line 10 def initialize(hash = {}) from_hash(hash) self.class::METADATA.each do |key, value| local_name = key local_name = value['local_name'] if value['local_name'] if value['max'] > 1 && instance_variable_get("@#{local_name}").nil? instance_variable_set("@#{local_name}".to_sym, []) end end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_name, *_args, &_block) ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/fhir_models/bootstrap/model.rb', line 39 def method_missing(method_name, *_args, &_block) if defined?(self.class::MULTIPLE_TYPES) && self.class::MULTIPLE_TYPES[method_name.to_s] self.class::MULTIPLE_TYPES[method_name.to_s].each do |type| type[0] = type[0].upcase value = send("#{method_name}#{type}".to_sym) return value unless value.nil? end return nil elsif !@extension.nil? && !@extension.empty? desired_extension = find_extension(@extension, method_name) unless desired_extension.first.nil? return desired_extension.first.value.nil? ? desired_extension.first : desired_extension.first.value end elsif !@modifierExtension.nil? && !@modifierExtension.empty? desired_extension = find_extension(@modifierExtension, method_name) unless desired_extension.first.nil? return desired_extension.first.value.nil? ? desired_extension.first : desired_extension.first.value end end raise NoMethodError.new("undefined method `#{method_name}' for #{self.class.name}", method_name) end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
allow two FHIR models to be compared for equality
34 35 36 |
# File 'lib/fhir_models/bootstrap/model.rb', line 34 def ==(other) self.class == other.class && to_hash == other.to_hash end |
#attribute_mismatch(left, right, exclude = []) ⇒ Object
84 85 86 87 88 89 90 |
# File 'lib/fhir_models/bootstrap/model.rb', line 84 def attribute_mismatch(left, right, exclude = []) if left.respond_to?(:mismatch) && right.respond_to?(:mismatch) left.mismatch right, exclude else compare_attribute(left, right, exclude) end end |
#compare_attribute(left, right, exclude = []) ⇒ Object
92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/fhir_models/bootstrap/model.rb', line 92 def compare_attribute(left, right, exclude = []) if left.respond_to?(:equals?) && right.respond_to?(:equals?) left.equals? right, exclude elsif left.is_a?(Array) && right.is_a?(Array) && (left.length == right.length) result = true (0...(left.length)).each { |i| result &&= compare_attribute(left[i], right[i], exclude) } result else left == right end end |
#each_element(path = nil, &block) ⇒ Object
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 |
# File 'lib/fhir_models/bootstrap/model.rb', line 310 def each_element(path = nil, &block) self.class::METADATA.each do |element_name, | local_name = .fetch :local_name, element_name values = [instance_variable_get("@#{local_name}")].flatten.compact next if values.empty? values.each_with_index do |value, i| child_path = if path.nil? element_name else "#{path}.#{element_name}" end child_path += "[#{i}]" if ['max'] > 1 yield value, , child_path value.each_element child_path, &block unless versioned_fhir_module::PRIMITIVES.include? ['type'] end end self end |
#equals?(other, exclude = []) ⇒ Boolean
65 66 67 68 69 70 |
# File 'lib/fhir_models/bootstrap/model.rb', line 65 def equals?(other, exclude = []) (self.class::METADATA.keys - exclude).each do |attribute| return false unless compare_attribute(instance_variable_get("@#{attribute}".to_sym), other.instance_variable_get("@#{attribute}".to_sym), exclude) end true end |
#hash ⇒ Object
This is necessary for uniq to properly identify two FHIR models as being identical
22 23 24 |
# File 'lib/fhir_models/bootstrap/model.rb', line 22 def hash to_hash.hash end |
#mismatch(other, exclude = []) ⇒ Object
72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/fhir_models/bootstrap/model.rb', line 72 def mismatch(other, exclude = []) misses = [] (self.class::METADATA.keys - exclude).each do |key| these = attribute_mismatch(instance_variable_get("@#{key}".to_sym), other.instance_variable_get("@#{key}".to_sym), exclude) if !these || (these.is_a?(Array) && !these.empty?) misses << "#{self.class}::#{key}" misses.concat these if these.is_a?(Array) end end misses end |
#primitive?(datatype, value) ⇒ Boolean
281 282 283 284 |
# File 'lib/fhir_models/bootstrap/model.rb', line 281 def primitive?(datatype, value) FHIR.logger.warn("prefer using FHIR.primitive? Called from #{caller.first}") FHIR.primitive?(datatype: datatype, value: value) end |
#respond_to_missing?(method_name) ⇒ Boolean
26 27 28 29 30 31 |
# File 'lib/fhir_models/bootstrap/model.rb', line 26 def respond_to_missing?(method_name, *) (defined?(self.class::MULTIPLE_TYPES) && self.class::MULTIPLE_TYPES[method_name.to_s]) || (!@extension.nil? && !@extension.empty? && !find_extension(@extension, method_name).first.nil?) || (!@modifierExtension.nil? && !@modifierExtension.empty? && !find_extension(@modifierExtension, method_name).first.nil?) || super end |
#to_reference ⇒ Object
61 62 63 |
# File 'lib/fhir_models/bootstrap/model.rb', line 61 def to_reference versioned_fhir_module::Reference.new(reference: "#{self.class.name.split('::').last}/#{id}") end |
#valid? ⇒ Boolean
104 105 106 |
# File 'lib/fhir_models/bootstrap/model.rb', line 104 def valid? validate.empty? end |
#validate(contained = nil) ⇒ Object
109 110 111 |
# File 'lib/fhir_models/bootstrap/model.rb', line 109 def validate(contained = nil) validate_profile(self.class::METADATA, contained) end |
#validate_profile(metadata, contained = nil) ⇒ Object
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/fhir_models/bootstrap/model.rb', line 113 def validate_profile(, contained = nil) contained_here = [instance_variable_get('@contained'.to_sym)].flatten contained_here << contained contained_here = contained_here.flatten.compact errors = {} .each do |field, | if .is_a?(Array) # this field has been 'sliced' .each do |slice| local_name = slice['local_name'] || field value = [instance_variable_get("@#{local_name}".to_sym)].flatten.compact subset = [] # subset is the values associated with just this slice if slice['type'] == 'Extension' subset = if slice['type_profiles'] value.select { |x| slice['type_profiles'].include?(x.url) } else value end else FHIR.logger.warn 'Validation not supported on slices (except for Extensions)' end validate_field(field, subset, contained_here, slice, errors) end else local_name = ['local_name'] || field value = [instance_variable_get("@#{local_name}".to_sym)].flatten.compact validate_field(field, value, contained_here, , errors) end end # metadata.each # check multiple types multiple_types = begin self.class::MULTIPLE_TYPES rescue StandardError {} end multiple_types.each do |prefix, suffixes| present = [] suffixes.each do |suffix| typename = "#{prefix}#{suffix[0].upcase}#{suffix[1..]}" # check which multiple data types are actually present, not just errors # actually, this might be allowed depending on cardinality value = instance_variable_get("@#{typename}") present << typename if !value.nil? || (value.is_a?(Array) && !value.empty?) end errors[prefix] = ["#{prefix}[x]: more than one type present."] if present.length > 1 # remove errors for suffixes that are not present next unless present.length == 1 suffixes.each do |suffix| typename = "#{prefix}#{suffix[0].upcase}#{suffix[1..]}" errors.delete(typename) unless present.include?(typename) end end errors.keep_if { |_k, v| (v && !v.empty?) } end |