Files
dunlop-core/app/models/dunlop/attribute_changes_tracking.rb
T
2018-01-20 13:02:44 -03:00

55 lines
1.7 KiB
Ruby

# Add tracking of last changed attributes. Models including this module will be able to track attribute changes like:
# record.last_changed[:backup_created] #=> timestamp or nil
# record.last_changed.backup_created #=> timestamp or nil
module Dunlop::AttributeChangesTracking
extend ActiveSupport::Concern
included do
attr_accessor :attribute_change_time # add ability to synchronize changed_at time for collections
has_many :last_attribute_changes, as: :target, class_name: 'Dunlop::LastAttributeChange'
after_update :update_last_attribute_changed_at
end
def update_last_attribute_changed_at
changed_at = attribute_change_time || Time.now
(saved_changes.keys - self.class.ignore_attributes_for_last_change).each do |attr|
if existing = last_attribute_changes.find{|changed| changed.attribute_name == attr }
existing.update(changed_at: changed_at)
else
last_attribute_changes.create(changed_at: changed_at, attribute_name: attr)
end
end
end
def last_changed
@last_changed ||= LastChanged.new(self)
end
module ClassMethods
def with_last_attribute_changes
includes(:last_attribute_changes)
end
def ignore_attributes_for_last_change
%w[id sti_type created_at updated_at notes]
end
end
class LastChanged
attr_reader :target
def initialize(target)
@target = target
end
def method_missing(m, *args)
raise "#{target.class.name} has no attribute #{m}" unless target.has_attribute?(m)
self[m]
end
def [](val)
target.last_attribute_changes.find{|changed| changed.attribute_name == val.to_s }.try(:changed_at)
end
end
end
# owner_initialization.last_changed[attr]