1# frozen_string_literal: true 2 3module ChronicDurationAttribute 4 extend ActiveSupport::Concern 5 6 class_methods do 7 def chronic_duration_attr_reader(virtual_attribute, source_attribute) 8 define_method(virtual_attribute) do 9 chronic_duration_attributes[virtual_attribute] || output_chronic_duration_attribute(source_attribute) 10 end 11 end 12 13 def chronic_duration_attr_writer(virtual_attribute, source_attribute, parameters = {}) 14 chronic_duration_attr_reader(virtual_attribute, source_attribute) 15 16 define_method("#{virtual_attribute}=") do |value| 17 chronic_duration_attributes[virtual_attribute] = value.presence || parameters[:default].presence.to_s 18 19 begin 20 new_value = value.present? ? ChronicDuration.parse(value).to_i : parameters[:default].presence 21 assign_attributes(source_attribute => new_value) 22 rescue ChronicDuration::DurationParseError 23 # ignore error as it will be caught by validation 24 end 25 end 26 27 validates virtual_attribute, allow_nil: true, duration: { message: parameters[:error_message] } 28 end 29 30 alias_method :chronic_duration_attr, :chronic_duration_attr_writer 31 end 32 33 def chronic_duration_attributes 34 @chronic_duration_attributes ||= {} 35 end 36 37 def output_chronic_duration_attribute(source_attribute) 38 value = attributes[source_attribute.to_s] 39 ChronicDuration.output(value, format: :short) if value 40 end 41end 42