Skip to content

Instantly share code, notes, and snippets.

@tbprojects
Created October 1, 2012 14:45
Show Gist options
  • Save tbprojects/3812217 to your computer and use it in GitHub Desktop.
Save tbprojects/3812217 to your computer and use it in GitHub Desktop.
[Ruby][ActiveRecord] log executing given methods with has_performable_actions
module PerformedActions
module Base
def self.included(base)
base.extend(ClassMethods)
end
def perform_action(action)
if self.class.get_performable_actions.include?(action.to_s)
PerformedAction.create!(subject: self,
performer_id: PerformedAction.current_user.try(:id),
performed_at: DateTime.now,
action: action)
else
raise SecurityError, "Not allowed to perform action '#{action}'"
end
end
def lately_performed(action)
PerformedAction.lately_performed(action, self)
end
def lately_performed_entry(action)
PerformedAction.lately_performed_entry(action, self)
end
module ClassMethods
def has_performable_actions(*args)
@performable_actions = args.map(&:to_s)
@performable_actions.each do |action|
instance_eval do
alias_method "original_#{action}".to_sym, action.to_sym
end
define_method action do
send "perform_action", action
send "original_#{action}"
end
end
end
def get_performable_actions
@performable_actions || []
end
end
end
end
ActiveRecord::Base.send(:include, PerformedActions::Base)
module PerformedActions
module Controller
def self.included(base)
base.before_filter :set_performer
end
private
def set_performer
PerformedAction.current_user = current_user
end
end
end
ApplicationController.send(:include, PerformedActions::Controller)
class PerformedAction < ActiveRecord::Base
default_scope :order => 'performed_at desc'
attr_accessible :subject, :performer_id, :performed_at, :action
include ActionView::Helpers::DateHelper
belongs_to :subject, polymorphic: true
belongs_to :performer, class_name: 'User'
validates :subject_id, :performed_at, :action, presence: true
def formatted_entry
"#{time_ago_in_words(performed_at)} (#{performer_full_name})"
end
def performer_full_name
performer ? performer.fullname : 'System'
end
def self.current_user
Thread.current[:user]
end
def self.current_user= user
Thread.current[:user] = user
end
def self.label_for_action(action)
I18n.t("performed_actions.#{action}")
end
def self.lately_performed_entry(action, subject)
lately_performed(action, subject).try(:formatted_entry) || I18n.t("performed_actions.never_entry")
end
def self.lately_performed(action, subject)
where(subject_type: subject.class.name, subject_id: subject.id).limit(1).search(action_eq: action, s: 'performed_at desc').result.first
end
end
#table structure:
# create_table :performed_actions do |t|
# t.integer :subject_id, null: false
# t.string :subject_type, null: false
# t.string :action, null: false
# t.integer :performer_id
# t.datetime :performed_at, null: false
#end
#
#usage:
# in model add 'has_performable_actions :method_one, :method_2' to log performing those methods
require "modules/performed_actions_base"
require "modules/performed_actions_controller"
require "modules/performed_actions_model"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment