Skip to content

Instantly share code, notes, and snippets.

@rossmari
Last active August 29, 2015 14:07
Show Gist options
  • Save rossmari/45d4cd0c1809a15d22a8 to your computer and use it in GitHub Desktop.
Save rossmari/45d4cd0c1809a15d22a8 to your computer and use it in GitHub Desktop.
Store changes for any model
class Magazine::EventLogger
attr_reader :history
FIELD_EXCEPTIONS = [:updated_at]
@namespace = 'Magazine::'
@suffix = 'Event'
def initialize(object)
@object = object
@history = {}
end
# store changed fields in hast and thet to DB
def process
changed_keys = @object.changed_attributes.keys
changed_keys.each do |key|
next if FIELD_EXCEPTIONS.include?(key.to_sym)
@history[key] = {before: preprocess_attribute(@object.changed_attributes[key], key),
now: preprocess_attribute(@object.attributes[key], key) }
end
end
# you can let logger to define owner class and id automaticaly or set them manualy
def write(owner_type = nil, owner_id = nil)
process
content = @history.to_json
type = owner_type || "#{@namespace}#{@object.class.name.demodulize}#{@suffix}"
Magazine::Event.create(owner_id: owner_id || @object.id, content: content, type: type)
end
def preprocess_attribute(value, key)
return value if value.blank?
result = case @object.class.columns_hash[key].type
when :datetime then I18n.l(value, format: :date_time)
when :boolean then (value ? 'Yes' : 'No')
else value
end
return result
end
end
# subscribe some model without of any params
#
# after_save :log_changes
# def log_changes
# logger = Magazine::EventLogger.new(self)
# logger.write
# end
# or set class and id (Link model belongs_to Set and I want to save Link events as Set events)
# def log_changes
# logger = Magazine::EventLogger.new(self)
# logger.write('Magazine::SetEvent', set.id)
# end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment