class VaccinationRecordTechnicalFieldsUpdater
Service object to update technically functional fields on a vaccination record Extracted so it can be reused by CLI commands like ‘vaccination-records edit` and `vaccination-records bulk-edit`.
Constants
- ALLOWED_ATTRIBUTES
- BOOLEAN_COLUMNS
- DATETIME_COLUMNS
- INTEGER_COLUMNS
Public Class Methods
Source
# File app/lib/vaccination_record_technical_fields_updater.rb, line 61 def self.call(...) = new(...).call private_class_method :new private attr_reader :record, :updates def coerce_value(key, value) # nil handling return nil if value.nil? return nil if value.is_a?(String) && value.strip.casecmp("nil").zero? # datetime if DATETIME_COLUMNS.include?(key) if value.respond_to?(:in_time_zone) return value elsif value.is_a?(String) t = Time.zone.parse(value) raise ArgumentError, "invalid datetime '#{value}'" if t.nil? return t else raise ArgumentError, "invalid datetime '#{value.inspect}'" end end # boolean if BOOLEAN_COLUMNS.include?(key) return value if [true, false].include?(value) return to_bool(value) if value.is_a?(String) raise ArgumentError, "invalid boolean '#{value.inspect}'" end # integer if INTEGER_COLUMNS.include?(key) return value.to_i if value.is_a?(Integer) return Integer(value) if value.is_a?(String) || value.is_a?(Numeric) raise ArgumentError, "invalid integer '#{value.inspect}'" end # default: pass through as-is (e.g. string) value end def to_bool(val) case val.strip.downcase when "true", "1", "yes", "y" true when "false", "0", "no", "n" false else raise ArgumentError, "invalid boolean '#{val}'" end end end
Source
# File app/lib/vaccination_record_technical_fields_updater.rb, line 35 def initialize(vaccination_record:, updates:) @record = vaccination_record @updates = updates end
Public Instance Methods
Source
# File app/lib/vaccination_record_technical_fields_updater.rb, line 40 def call unless updates.is_a?(Hash) raise "updates must be a Hash of attribute=>value" end parsed_updates = {} updates.each do |raw_key, raw_value| key = raw_key.to_s unless ALLOWED_ATTRIBUTES.include?(key) raise "Attribute '#{key}' is not editable by this tool" end parsed_updates[key] = coerce_value(key, raw_value) end record.assign_attributes(parsed_updates) record.save!(touch: false) end
Source
# File app/lib/vaccination_record_technical_fields_updater.rb, line 69 def coerce_value(key, value) # nil handling return nil if value.nil? return nil if value.is_a?(String) && value.strip.casecmp("nil").zero? # datetime if DATETIME_COLUMNS.include?(key) if value.respond_to?(:in_time_zone) return value elsif value.is_a?(String) t = Time.zone.parse(value) raise ArgumentError, "invalid datetime '#{value}'" if t.nil? return t else raise ArgumentError, "invalid datetime '#{value.inspect}'" end end # boolean if BOOLEAN_COLUMNS.include?(key) return value if [true, false].include?(value) return to_bool(value) if value.is_a?(String) raise ArgumentError, "invalid boolean '#{value.inspect}'" end # integer if INTEGER_COLUMNS.include?(key) return value.to_i if value.is_a?(Integer) return Integer(value) if value.is_a?(String) || value.is_a?(Numeric) raise ArgumentError, "invalid integer '#{value.inspect}'" end # default: pass through as-is (e.g. string) value end
Source
# File app/lib/vaccination_record_technical_fields_updater.rb, line 105 def to_bool(val) case val.strip.downcase when "true", "1", "yes", "y" true when "false", "0", "no", "n" false else raise ArgumentError, "invalid boolean '#{val}'" end end