Skip to content

Instantly share code, notes, and snippets.

@kossnocorp
Created December 7, 2009 04:10
Show Gist options
  • Select an option

  • Save kossnocorp/250606 to your computer and use it in GitHub Desktop.

Select an option

Save kossnocorp/250606 to your computer and use it in GitHub Desktop.
module Loggable
def self.included base
base.send :extend, ClassMethods
end
module ClassMethods
def acts_as_loggable loggable = :all, rules = {}
cattr_accessor :loggable_actions, :loggable_rules
if loggable.class == Hash
self.loggable_actions = :all
self.loggable_rules = loggable
else
self.loggable_actions = loggable
self.loggable_rules = rules
end
send :include, InstanceMethods
end
end
module InstanceMethods
def after_create
add_loggable_row 'create'
end
def after_update
add_loggable_row 'update'
end
def after_destroy
add_loggable_row 'destroy'
end
private
def loggable? action
loggable_actions = self.class.loggable_actions
if loggable_actions == :all or \
(loggable_actions.class == Array and
loggable_actions.include? action.to_sym) or
loggable_actions == action.to_sym
true
else
false
end
end
def current_user
session = UserSession.find
return session.user if session
nil
end
def add_loggable_row action
return unless loggable?(action)
object_hash = {
:user => current_user,
:model => self.class.to_s,
:action => action,
:updated_id => id
}
create_object = nil
loggable_attributes = self.class.loggable_rules[:loggable_attrs]
if action == 'update' and loggable_attributes
changed.each do |attr|
if loggable_attributes == attr.to_sym or
(loggable_attributes.class == Array and
loggable_attributes.include? attr.to_sym)
create_object = [] unless create_object
create_object << object_hash.merge(
:updated_attribute => attr,
:public => loggable_action_is_public?(action, attr.to_sym)
)
end
end
else
create_object = object_hash.merge(
:public => loggable_action_is_public?(action)
)
end
Update.create create_object if create_object
end
def loggable_action_is_public? action, attribute = ''
public_rules = self.class.loggable_rules[:public]
return false unless public_rules
if attribute == ''
case public_rules
when action.to_sym
true
when :all
true
else
result = false
if public_rules.class == Array and public_rules.include? action.to_sym
result = true
end
result
end
else
public_attributes = self.class.loggable_rules[:public_attrs]
if public_attributes and \
(public_attributes.include? attribute.to_sym or
public_attributes == attribute.to_sym)
true
else
false
end
end
end
end
end
ActiveRecord::Base.send :include, Loggable
class CreateUpdates < ActiveRecord::Migration
def self.up
create_table :updates do |t|
t.string :model
t.string :action
t.references :user
t.string :updated_attribute
t.integer :updated_id
t.boolean :public
t.timestamps
end
end
def self.down
drop_table :updates
end
end
class Album < ActiveRecord::Base
...
acts_as_loggable \
:public => [:create, :update],
:loggable_attrs => [:cover_file_name, :description],
:public_attrs => [:cover_file_name, :description]
...
end
class Artist < ActiveRecord::Base
...
acts_as_loggable \
:public => [:create, :update],
:loggable_attrs => [:description],
:public_attrs => [:description]
...
end
class City < ActiveRecord::Base
...
acts_as_loggable
...
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment