I have a concern that allows me to mark a model in my Rails app as “Durationable”. Something like this:
module Durationable
extend ActiveSupport::Concern
included do
attr_accessor :duration_years, :duration_months, ... etc
after_initialize(unless: :new_record?) do |record|
duration = record.read_attribute(durationable_field_name)
@duration_years = record.duration&.parts&.dig(:years) || 0
@duration_months = record.duration&.parts&.dig(:months) || 0
...etc
end
before_save do |record|
record.duration = (@duration_years.to_i.years + @duration_months.to_i.months ... etc)
end
end
end
This worked fine on my model:
class Task < ApplicationRecord
include Durationable
end
It turns out that I now have a model that has two “duration” fields - say booked_duration
and actual_duration
. My concern doesn’t seem particularly well suited as it only copes with a single duration field.
I was thinking of being able to define my model with something like:
class Task < ApplicationRecord
include Durationable
acts_as_duration :booked_duration
acts_as_duration :actual_duration
end
I would then define a class method in the concern called acts_as_duration
that manags an array of duration fields and add similar behaviour to the original concern, but operating over these multiple fields.
Does this seem like a good/suitable use of concerns? I can certainly get something functional working, but I wonder if there is a better suited pattern? It seems strange to include Durationable
but that doesn’t actually do anything until a call to acts_as_duration
?
Would really appreciate any thoughts on the best way to architect this.