Skip to content

Instantly share code, notes, and snippets.

@jgaskins
Created September 30, 2017 17:39
Show Gist options
  • Save jgaskins/9802b85eb22c70ba924d6d7604e7a00a to your computer and use it in GitHub Desktop.
Save jgaskins/9802b85eb22c70ba924d6d7604e7a00a to your computer and use it in GitHub Desktop.
Data provenance with Neo4j.rb
module Auditable
def audit model_name: :audits, method_name: :audit
define_method method_name do |info={}|
from = changed_attributes.to_h
to = from.each_key.each_with_object({}) do |key, hash|
hash[key] = self[key]
end
@__current_audit = {
from: from,
to: to,
# Allow multiple audit calls to just merge the info
info: (@__current_audit || { info: {} })[:info].merge(info),
model: self,
}
end
before_update method_name
after_update_commit do
Entry.create @__current_audit if @__current_audit
@__current_audit = nil
end
has_many :in, model_name, type: :AUDITS, model_class: 'Auditable::Entry'
end
class Entry
include Neo4j::ActiveNode
property :from
property :to
property :info
property :created_at
serialize :from
serialize :to
serialize :info
has_one :out, :model, type: :AUDITS, model_class: false
end
end
class User
include Neo4j::ActiveNode
extend Auditable
audit model_name: :audits, method_name: :audit
property :email, type: String
property :name, type: String
end
me = User.create!(email: '[email protected]', name: 'Me')
me.audit reason: 'Oops, wrong name'
me.update! name: 'Myself'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment