module Ecom module Core class MeasurementUnit < ApplicationRecord METRIC = 'Metric'.freeze IMPERIAL = 'Imperial'.freeze SYSTEM_OF_MEASURMENT = [METRIC, IMPERIAL].freeze # commonly used physical quantities in construction LENGTH = 'Length'.freeze MASS = 'Mass'.freeze TIME = 'Time'.freeze CURRENT = 'Current'.freeze TEMPRATURE = 'Temprature'.freeze AREA = 'Area'.freeze VOLUME = 'Volume'.freeze ENERGY = 'Energy'.freeze DENSITY = 'DENSITY'.freeze PHYSICAL_QUANTITIES = [LENGTH, MASS, TIME, CURRENT, TEMPRATURE, AREA, VOLUME, ENERGY, DENSITY].freeze validates :name, :abbrivation, :physical_quantity, :conversion_factor, :system_of_measurement, presence: true validates :is_si_unit, inclusion: { in: [true, false] } validates :system_of_measurement, inclusion: SYSTEM_OF_MEASURMENT validates :physical_quantity, inclusion: PHYSICAL_QUANTITIES validate :si_unit_with_conversion_factor validate :si_unit_system_of_measurement_and_physical_quantity def si_unit_with_conversion_factor if is_si_unit && conversion_factor != 1 errors.add(:base, 'Conversion factor for an SI unit has to be 1') elsif !is_si_unit && conversion_factor == 1 errors.add(:base, 'Only SI units can have a conversion factor 1') end end # scope si unit with system of measurement and physical quantity def si_unit_system_of_measurement_and_physical_quantity return if system_of_measurement.nil? || physical_quantity.nil? existing_record = MeasurementUnit .where(system_of_measurement: system_of_measurement, physical_quantity: physical_quantity, is_si_unit: true).first return unless (new_record? && existing_record.present?) || (persisted? && existing_record != self) errors.add(:is_si_unit, 'There exist an si unit of measurement for the given physical quantity and system of measurement') end end end end