Skip to content

Instantly share code, notes, and snippets.

@dpmccabe
Created October 2, 2012 20:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dpmccabe/3823102 to your computer and use it in GitHub Desktop.
Save dpmccabe/3823102 to your computer and use it in GitHub Desktop.
event tracking with mongoid
module ApplicationHelper
def event_autolink(event_parts)
event_parts.map do |part|
case part.content
when Hash
link_to part.content['name'], send("admin_#{part.content['class_name'].underscore}_path", part.content['id'])
else
part.content
end
end.join(' ').html_safe
end
end
class Event
include Mongoid::Document
include Mongoid::Timestamps
embeds_many :event_parts
paginates_per 50
def self.record(*parts)
Event.create(event_parts: parts.map { |part| EventPart.serialize_and_initialize(part) })
end
def self.fetch(*parts)
parts.inject(Event) do |criteria, part|
if part.class.superclass == ActiveRecord::Base
criteria.where('event_parts.content.class_name' => part.class.name, 'event_parts.content.id' => part.id)
else
criteria.where('event_parts.content' => part)
end
end
end
end
class EventPart
include Mongoid::Document
embedded_in :event
field :content
def self.serialize_and_initialize(obj)
if obj.class.superclass == ActiveRecord::Base
EventPart.new(content: { name: obj.name, class_name: obj.class.name, id: obj.id })
else
EventPart.new(content: obj)
end
end
end
require 'spec_helper'
describe Event do
let(:user) { FactoryGirl.create(:user, fname: 'John', lname: 'Doe') }
let(:subject) { FactoryGirl.create(:subject) }
it 'should record an Event of varying parts' do
event = Event.record(user, 'enrolled in', subject, 'and it was good')
event.should have(4).event_parts
event.event_parts.first.content.should eq({
name: 'John Doe',
class_name: 'User',
id: user.id
})
event.event_parts.last.content.should eq('and it was good')
end
it 'should fetch events for some object' do
Event.record(user, 'signed up')
Event.record(user, 'enrolled in', subject)
events = Event.fetch(user)
events.size.should eq(2)
end
end
describe EventPart do
let(:user) { FactoryGirl.create(:user, fname: 'John', lname: 'Doe') }
it 'should serialize and initialize an EventPart from a user' do
event_part = EventPart.serialize_and_initialize(user)
event_part.content.should eq({
name: 'John Doe',
class_name: 'User',
id: user.id
})
end
end
ActiveAdmin.register_page 'Events' do
menu if: proc{ can?(:manage, Event) }, parent: 'Logs'
content do
table class: 'index_table' do
thead do
tr do
th 'Event'
th 'When'
end
end
tbody do
(@events = Event.desc(:created_at).page(params[:page])).each do |event|
tr class: cycle('odd', 'even') do
td event_autolink(event.event_parts)
td do
span style: 'white-space: nowrap' do
event.created_at.strftime("%b %d, %Y %I:%M:%S %p")
end
end
end
end
end
end
div id: 'index_footer' do
paginate @events
end
end
end
Event.record(user, 'signed up')
Event.record(user, 'enrolled in', subject)
Event.record(product, 'sold out')
Event.fetch(user) # all of a user's events
Event.fetch(user, 'enrolled in', subject) # events where a user enrolled in a particular subject
Event.fetch(user, subject) # all events associated with a user and a particular subject
Event.fetch('signed up') # all signup events
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment