tyler-makes_events 0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.textile +41 -0
- data/Rakefile +22 -0
- data/generators/makes_events/USAGE +8 -0
- data/generators/makes_events/makes_events_generator.rb +15 -0
- data/generators/makes_events/templates/migrate/create_events.rb +17 -0
- data/generators/makes_events/templates/models/event.rb +4 -0
- data/init.rb +1 -0
- data/install.rb +1 -0
- data/lib/makes_events.rb +85 -0
- data/makes_events.gemspec +32 -0
- data/tasks/makes_events_tasks.rake +4 -0
- data/test/makes_events_test.rb +8 -0
- data/uninstall.rb +1 -0
- metadata +79 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 [name of plugin creator]
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.textile
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
h1. MakesEvents
|
2
|
+
|
3
|
+
|
4
|
+
h2. Overview
|
5
|
+
|
6
|
+
MakesEvents makes it easy to create running logs of user activity. Why would you want to do that? Well, the reason I made it is because I wanted a Facebook-like feed of recent user activity on a particular site (heavyink.com). The naive first-pass implementation involved grabbing the records from the last x days for a particular user from a variety of tables. (Something like 20.) This obviously would not scale. What you'd actually want to do is just note particular user activity in a single table so you can just select from there and be done with it.
|
7
|
+
|
8
|
+
|
9
|
+
h2. Example
|
10
|
+
|
11
|
+
<pre>
|
12
|
+
<code>
|
13
|
+
class User < ActiveRecord::Base
|
14
|
+
owns_events
|
15
|
+
end
|
16
|
+
|
17
|
+
class Pet < ActiveRecord::Base
|
18
|
+
belongs_to :user
|
19
|
+
|
20
|
+
makes_events :owner => :user do
|
21
|
+
event :new_pet, :after_create
|
22
|
+
event :pet_died, :after_destroy
|
23
|
+
event :pet_changed_names, :after_update, :changed => :name
|
24
|
+
event :got_a_monkey, :after_save do |pet|
|
25
|
+
pet.type_changed? && pet.type == 'monkey'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
</code>
|
30
|
+
</pre>
|
31
|
+
|
32
|
+
Here we have a trivial example where we have Users who have Pets. We want to log every time a user saves a new pet, deletes a pet, changes a pet's name, or when the pet is a monkey.
|
33
|
+
|
34
|
+
First we say that Pets make events using the _makes_events_ method. We can pass a hash of options to that method which propagate down to the individual _event_ methods within the block.
|
35
|
+
|
36
|
+
The individual _event_ calls are fairly straightforward. The first creates the :new_pet event type, which gets triggered on the _after_create_ callback. Likewise, we make a :pet_died event type which gets triggered on the _after_destroy_ callback.
|
37
|
+
|
38
|
+
The third _event_ is slightly more complicated in that it relies on the :changed option. In this case, we want the event to be triggered on the _after_update_ callback, but only if the _name_ field has changed. (This relies on Rails 2.1's Dirty fields functionality.)
|
39
|
+
|
40
|
+
The last _event_ call is more complicated yet. Passing a block to _event_ allows you to control whether or not the event is triggered based on the return value of that block. In this case, the event will only be triggered if the pet's type has been set to "monkey". One important note is that the block you pass to it will actually be run in a _before_save_ callback. This allows you to check whether a field has been changed and trigger the event based on that.
|
41
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
desc 'Default: run unit tests.'
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
desc 'Test the makes_events plugin.'
|
9
|
+
Rake::TestTask.new(:test) do |t|
|
10
|
+
t.libs << 'lib'
|
11
|
+
t.pattern = 'test/**/*_test.rb'
|
12
|
+
t.verbose = true
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Generate documentation for the makes_events plugin.'
|
16
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
17
|
+
rdoc.rdoc_dir = 'rdoc'
|
18
|
+
rdoc.title = 'MakesEvents'
|
19
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
20
|
+
rdoc.rdoc_files.include('README')
|
21
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
22
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class MakesEventsGenerator < Rails::Generator::NamedBase
|
2
|
+
def initialize(runtime_args, runtime_options={})
|
3
|
+
super
|
4
|
+
end
|
5
|
+
|
6
|
+
def manifest
|
7
|
+
record do |m|
|
8
|
+
m.directory File.join('app/models')
|
9
|
+
m.directory File.join('db/migrate')
|
10
|
+
|
11
|
+
m.migration_template 'migrate/create_events.rb', 'db/migrate'
|
12
|
+
m.file 'models/event.rb', 'app/models/event.rb'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class CreateEvents < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :events do |t|
|
4
|
+
t.integer :owner_id
|
5
|
+
t.string :owner_type
|
6
|
+
t.integer :target_id
|
7
|
+
t.string :target_type
|
8
|
+
t.string :event_type
|
9
|
+
|
10
|
+
t.timestamps
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.down
|
15
|
+
drop_table :events
|
16
|
+
end
|
17
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'lib', 'makes_events.rb')
|
data/install.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Install hook code here
|
data/lib/makes_events.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
module MakesEvents
|
2
|
+
module ClassMethods
|
3
|
+
def makes_events(options={})
|
4
|
+
extend MakesEvents::MakerMethods::ClassMethods
|
5
|
+
include MakesEvents::MakerMethods::InstanceMethods
|
6
|
+
|
7
|
+
has_many :events, :as => :target
|
8
|
+
|
9
|
+
@_makes_events_make_options = options
|
10
|
+
yield
|
11
|
+
end
|
12
|
+
|
13
|
+
def owns_events
|
14
|
+
extend MakesEvents::OwnerMethods::ClassMethods
|
15
|
+
include MakesEvents::OwnerMethods::InstanceMethods
|
16
|
+
|
17
|
+
has_many :events, :as => :owner
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module MakerMethods
|
22
|
+
module ClassMethods
|
23
|
+
def event(type, happens, options={}, &block)
|
24
|
+
set_conditional(type,&block) if block
|
25
|
+
|
26
|
+
field = options.delete(:changed)
|
27
|
+
set_change_conditional(type,field) if field
|
28
|
+
|
29
|
+
send(happens) do |object|
|
30
|
+
check = !@_makes_event_checks ||
|
31
|
+
!@_makes_event_checks.has_key?(type) ||
|
32
|
+
@_makes_event_checks.delete(type)
|
33
|
+
log_event(type, object, options) if check
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def log_event(type, object, options={})
|
38
|
+
options = @_makes_events_make_options.merge(options)
|
39
|
+
|
40
|
+
Event.create :event_type => type.to_s,
|
41
|
+
:target => object,
|
42
|
+
:owner => options[:owner] ? object.send(options[:owner]) : object.owner
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def set_change_conditional(type,field)
|
48
|
+
return set_conditional(type) { |o| o.changed? } if field == true
|
49
|
+
set_conditional(type) { |o| o.send("#{field}_changed?") }
|
50
|
+
end
|
51
|
+
|
52
|
+
def set_conditional(type,&block)
|
53
|
+
send(:before_save) { |object|
|
54
|
+
@_makes_event_checks ||= {}
|
55
|
+
@_makes_event_checks[type] = !!block.call(object)
|
56
|
+
true
|
57
|
+
}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
module InstanceMethods
|
62
|
+
def log_event(type, options={})
|
63
|
+
self.class.log_event(type,self,options)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
module OwnerMethods
|
69
|
+
module ClassMethods
|
70
|
+
def recent_events(users,date=15.days.ago)
|
71
|
+
Event.find(:all,
|
72
|
+
:conditions => ["owner_type = ? AND owner_id in (?) AND created_at >= ?",
|
73
|
+
self.to_s, users.map(&:id), date])
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
module InstanceMethods
|
78
|
+
def recent_events(date=15.days.ago)
|
79
|
+
self.events.find(:all, :conditions => ["created_at >= ?", date])
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
ActiveRecord::Base.extend MakesEvents::ClassMethods
|
@@ -0,0 +1,32 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "makes_events"
|
3
|
+
s.version = "0.6"
|
4
|
+
s.date = "2008-09-29"
|
5
|
+
s.summary = "Easy event logger plugin for Rails 2.1."
|
6
|
+
s.email = "tbmcmullen@gmail.com"
|
7
|
+
s.homepage = "http://github.com/tyler/makes_events"
|
8
|
+
s.description = "Easy event logger plugin for Rails 2.1. (Think: Facebook's recent activity feed.)"
|
9
|
+
s.has_rdoc = false
|
10
|
+
s.authors = ["Tyler McMullen"]
|
11
|
+
s.files = ["generators",
|
12
|
+
"makes_events.gemspec",
|
13
|
+
"install.rb",
|
14
|
+
"uninstall.rb",
|
15
|
+
"init.rb",
|
16
|
+
"README.textile",
|
17
|
+
"Rakefile",
|
18
|
+
"MIT-LICENSE",
|
19
|
+
"generators/makes_events",
|
20
|
+
"lib/makes_events.rb",
|
21
|
+
"tasks/makes_events_tasks.rake",
|
22
|
+
"test/makes_events_test.rb",
|
23
|
+
"generators/makes_events/templates",
|
24
|
+
"generators/makes_events/USAGE",
|
25
|
+
"generators/makes_events/makes_events_generator.rb",
|
26
|
+
"generators/makes_events/templates/migrate",
|
27
|
+
"generators/makes_events/templates/models",
|
28
|
+
"generators/makes_events/templates/migrate/create_events.rb",
|
29
|
+
"generators/makes_events/templates/models/event.rb"]
|
30
|
+
|
31
|
+
s.add_dependency("activerecord", ["> 2.1.0"])
|
32
|
+
end
|
data/uninstall.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Uninstall hook code here
|
metadata
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tyler-makes_events
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "0.6"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tyler McMullen
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-09-29 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: activerecord
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 2.1.0
|
23
|
+
version:
|
24
|
+
description: "Easy event logger plugin for Rails 2.1. (Think: Facebook's recent activity feed.)"
|
25
|
+
email: tbmcmullen@gmail.com
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files: []
|
31
|
+
|
32
|
+
files:
|
33
|
+
- generators
|
34
|
+
- makes_events.gemspec
|
35
|
+
- install.rb
|
36
|
+
- uninstall.rb
|
37
|
+
- init.rb
|
38
|
+
- README.textile
|
39
|
+
- Rakefile
|
40
|
+
- MIT-LICENSE
|
41
|
+
- generators/makes_events
|
42
|
+
- lib/makes_events.rb
|
43
|
+
- tasks/makes_events_tasks.rake
|
44
|
+
- test/makes_events_test.rb
|
45
|
+
- generators/makes_events/templates
|
46
|
+
- generators/makes_events/USAGE
|
47
|
+
- generators/makes_events/makes_events_generator.rb
|
48
|
+
- generators/makes_events/templates/migrate
|
49
|
+
- generators/makes_events/templates/models
|
50
|
+
- generators/makes_events/templates/migrate/create_events.rb
|
51
|
+
- generators/makes_events/templates/models/event.rb
|
52
|
+
has_rdoc: false
|
53
|
+
homepage: http://github.com/tyler/makes_events
|
54
|
+
post_install_message:
|
55
|
+
rdoc_options: []
|
56
|
+
|
57
|
+
require_paths:
|
58
|
+
- lib
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: "0"
|
64
|
+
version:
|
65
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: "0"
|
70
|
+
version:
|
71
|
+
requirements: []
|
72
|
+
|
73
|
+
rubyforge_project:
|
74
|
+
rubygems_version: 1.2.0
|
75
|
+
signing_key:
|
76
|
+
specification_version: 2
|
77
|
+
summary: Easy event logger plugin for Rails 2.1.
|
78
|
+
test_files: []
|
79
|
+
|