eventifier 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -1
- data/.travis.yml +14 -0
- data/Gemfile.lock +17 -3
- data/README.textile +7 -2
- data/Rakefile +1 -8
- data/eventifier.gemspec +7 -3
- data/lib/eventifier/active_record/event.rb +9 -0
- data/lib/eventifier/active_record/event_observer.rb +8 -0
- data/lib/eventifier/active_record/event_tracking.rb +11 -0
- data/lib/eventifier/active_record/ghost.rb +9 -0
- data/lib/eventifier/active_record/notification.rb +13 -0
- data/lib/eventifier/active_record_support.rb +5 -0
- data/lib/eventifier/event_mixin.rb +45 -0
- data/lib/eventifier/event_observer_mixin.rb +44 -0
- data/lib/eventifier/event_tracking.rb +29 -18
- data/lib/eventifier/ghost_mixin.rb +27 -0
- data/lib/eventifier/helper_methods.rb +2 -0
- data/lib/eventifier/mongoid/event.rb +16 -0
- data/lib/eventifier/mongoid/event_observer.rb +7 -0
- data/lib/eventifier/mongoid/event_tracking.rb +13 -0
- data/lib/eventifier/mongoid/ghost.rb +15 -0
- data/lib/eventifier/mongoid/notification.rb +19 -0
- data/lib/eventifier/mongoid/user_patch.rb +3 -0
- data/lib/eventifier/mongoid_support.rb +6 -0
- data/lib/eventifier/notification_helper.rb +4 -13
- data/lib/eventifier/notification_mailer.rb +5 -1
- data/lib/eventifier/notification_mixin.rb +42 -0
- data/lib/eventifier/version.rb +1 -1
- data/lib/eventifier.rb +8 -10
- data/lib/generators/eventifier/install/install_generator.rb +1 -1
- data/spec/event_helper_spec.rb +45 -35
- data/spec/event_observer_spec.rb +1 -6
- data/spec/event_spec.rb +16 -5
- data/spec/event_tracking_spec.rb +20 -0
- data/spec/eventifier_spec.rb +48 -52
- data/spec/fabricators/fabricator.rb +31 -0
- data/spec/ghost_spec.rb +30 -0
- data/spec/helper_methods_spec.rb +2 -2
- data/spec/integration/eventifier_spec.rb +85 -44
- data/spec/notification_helper_spec.rb +13 -6
- data/spec/notification_mailer_spec.rb +6 -1
- data/spec/notification_spec.rb +9 -11
- data/spec/spec_helper.rb +11 -2
- data/spec/support/database_cleaner.rb +3 -0
- data/spec/support/model_helpers.rb +36 -0
- data/spec/{support → test_classes}/active_record_support.rb +9 -0
- data/spec/test_classes/mongoid_support.rb +34 -0
- metadata +94 -24
- data/lib/eventifier/event.rb +0 -35
- data/lib/eventifier/event_observer.rb +0 -35
- data/lib/eventifier/notification.rb +0 -40
- data/spec/support/blueprints.rb +0 -24
data/.gitignore
CHANGED
data/.travis.yml
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
# - 1.8.7
|
4
|
+
- 1.9.2
|
5
|
+
- 1.9.3
|
6
|
+
# - jruby-18mode # JRuby in 1.8 mode
|
7
|
+
# - jruby-19mode # JRuby in 1.9 mode
|
8
|
+
|
9
|
+
env:
|
10
|
+
- ORM=active_record
|
11
|
+
- ORM=mongoid
|
12
|
+
|
13
|
+
before_script:
|
14
|
+
- psql -c 'create database eventifier;' -U postgres
|
data/Gemfile.lock
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
eventifier (0.0.
|
4
|
+
eventifier (0.0.2)
|
5
5
|
actionmailer
|
6
6
|
actionmailer
|
7
7
|
activerecord
|
8
|
+
bson_ext
|
9
|
+
mongoid
|
8
10
|
|
9
11
|
GEM
|
10
12
|
remote: http://rubygems.org/
|
@@ -34,18 +36,28 @@ GEM
|
|
34
36
|
i18n (~> 0.6)
|
35
37
|
multi_json (~> 1.0)
|
36
38
|
arel (3.0.2)
|
39
|
+
bson (1.6.4)
|
40
|
+
bson_ext (1.6.3)
|
41
|
+
bson (~> 1.6.3)
|
37
42
|
builder (3.0.0)
|
43
|
+
database_cleaner (0.7.2)
|
38
44
|
diff-lcs (1.1.3)
|
39
45
|
erubis (2.7.0)
|
46
|
+
fabrication (1.4.0)
|
40
47
|
hike (1.2.1)
|
41
48
|
i18n (0.6.0)
|
42
49
|
journey (1.0.3)
|
43
|
-
machinist (2.0)
|
44
50
|
mail (2.4.4)
|
45
51
|
i18n (>= 0.4.0)
|
46
52
|
mime-types (~> 1.16)
|
47
53
|
treetop (~> 1.4.8)
|
48
54
|
mime-types (1.18)
|
55
|
+
mongo (1.6.2)
|
56
|
+
bson (~> 1.6.2)
|
57
|
+
mongoid (2.4.11)
|
58
|
+
activemodel (~> 3.1)
|
59
|
+
mongo (<= 1.6.2)
|
60
|
+
tzinfo (~> 0.3.22)
|
49
61
|
multi_json (1.3.6)
|
50
62
|
pg (0.13.2)
|
51
63
|
polyglot (0.3.3)
|
@@ -77,7 +89,9 @@ PLATFORMS
|
|
77
89
|
|
78
90
|
DEPENDENCIES
|
79
91
|
activerecord
|
92
|
+
database_cleaner
|
80
93
|
eventifier!
|
81
|
-
|
94
|
+
fabrication
|
95
|
+
mongoid
|
82
96
|
pg
|
83
97
|
rspec
|
data/README.textile
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
!https://secure.travis-ci.org/inspire9/eventifier.png!:http://travis-ci.org/inspire9/eventifier
|
2
|
+
|
1
3
|
h1. Eventifier
|
2
4
|
|
3
5
|
Event tracking and notifying for active record models
|
@@ -9,6 +11,7 @@ Send notifications of events
|
|
9
11
|
|
10
12
|
h2. Example
|
11
13
|
|
14
|
+
<pre><code>
|
12
15
|
class EventTracking
|
13
16
|
include Eventifier::EventTracking
|
14
17
|
|
@@ -16,6 +19,7 @@ class EventTracking
|
|
16
19
|
events_for Post do
|
17
20
|
track_on [:create, :update, :destroy], :attributes => { :except => %w(updated_at) }
|
18
21
|
notify :group => :members, :on => [:create, :update]
|
22
|
+
url -> post { [post.category, post] }
|
19
23
|
end
|
20
24
|
|
21
25
|
events_for Announcement do
|
@@ -24,6 +28,7 @@ class EventTracking
|
|
24
28
|
end
|
25
29
|
end
|
26
30
|
end
|
31
|
+
</code></pre>
|
27
32
|
|
28
33
|
That's it!
|
29
34
|
|
@@ -38,9 +43,9 @@ Creating the database:
|
|
38
43
|
* createdb eventifier
|
39
44
|
|
40
45
|
Spec
|
41
|
-
|
46
|
+
<pre><code>
|
42
47
|
rspec spec
|
43
|
-
|
48
|
+
</code></pre>
|
44
49
|
|
45
50
|
h2. Contributors
|
46
51
|
|
data/Rakefile
CHANGED
@@ -1,13 +1,6 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
|
-
|
3
|
-
require 'rake'
|
4
2
|
require 'rspec/core/rake_task'
|
5
|
-
require 'rdoc/task'
|
6
|
-
|
7
3
|
|
8
4
|
RSpec::Core::RakeTask.new
|
9
5
|
|
10
|
-
|
11
|
-
spec.rcov = true
|
12
|
-
spec.rcov_opts = ['--exclude', 'spec', '--exclude', '.rvm']
|
13
|
-
end
|
6
|
+
task :default => :spec
|
data/eventifier.gemspec
CHANGED
@@ -5,7 +5,7 @@ require "eventifier/version"
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = "eventifier"
|
7
7
|
s.version = Eventifier::VERSION
|
8
|
-
s.authors = ["Nathan Sampimon"]
|
8
|
+
s.authors = ["Nathan Sampimon", "Peter Murray"]
|
9
9
|
s.email = ["nathan@inspire9.com"]
|
10
10
|
s.homepage = "http://github.com/inspire9/eventifier"
|
11
11
|
s.summary = "Event tracking and notifying for active record models"
|
@@ -15,15 +15,19 @@ Gem::Specification.new do |s|
|
|
15
15
|
|
16
16
|
s.files = `git ls-files`.split("\n")
|
17
17
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
21
|
s.add_development_dependency "activerecord"
|
22
|
+
s.add_development_dependency "mongoid"
|
22
23
|
s.add_runtime_dependency "actionmailer"
|
23
|
-
s.add_development_dependency "
|
24
|
+
s.add_development_dependency "fabrication"
|
25
|
+
s.add_development_dependency "database_cleaner"
|
24
26
|
s.add_development_dependency "pg"
|
25
27
|
s.add_development_dependency "rspec"
|
26
28
|
|
27
29
|
s.add_runtime_dependency "activerecord"
|
30
|
+
s.add_runtime_dependency "bson_ext"
|
31
|
+
s.add_runtime_dependency "mongoid"
|
28
32
|
s.add_runtime_dependency "actionmailer"
|
29
33
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Eventifier
|
2
|
+
module EventTracking
|
3
|
+
OBSERVER_CLASS = ActiveRecord::Observer
|
4
|
+
|
5
|
+
def add_notification_association(target_klass)
|
6
|
+
target_klass.class_eval do
|
7
|
+
has_many :notifications, :through => :events, :class_name => 'Eventifier::Notification', :dependent => :destroy
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'eventifier/notification_mixin'
|
2
|
+
|
3
|
+
module Eventifier
|
4
|
+
class Notification < ActiveRecord::Base
|
5
|
+
include Eventifier::NotificationMixin
|
6
|
+
|
7
|
+
default_scope order("created_at DESC")
|
8
|
+
scope :for_events, -> ids { where(event_id: ids) }
|
9
|
+
scope :for_user, -> user { where(user_id: user.id) }
|
10
|
+
scope :since, -> date { where("created_at > ?", date) }
|
11
|
+
scope :latest, order('notifications.created_at DESC').limit(5)
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Eventifier
|
4
|
+
module EventMixin
|
5
|
+
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
belongs_to :user
|
10
|
+
belongs_to :eventable, :polymorphic => true
|
11
|
+
has_many :notifications, :class_name => 'Eventifier::Notification'
|
12
|
+
|
13
|
+
validates :user, :presence => true
|
14
|
+
validates :eventable, :presence => true
|
15
|
+
validates :verb, :presence => true
|
16
|
+
end
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
|
20
|
+
def add_notification(*arg)
|
21
|
+
observer_instances.each { |observer| observer.add_notification(*arg) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_url(*arg)
|
25
|
+
observer_instances.each { |observer| observer.add_url(*arg) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def create_event(verb, object, options = { })
|
29
|
+
changed_data = object.changes.stringify_keys
|
30
|
+
changed_data = changed_data.reject { |attribute, value| options[:except].include?(attribute) } if options[:except]
|
31
|
+
changed_data = changed_data.select { |attribute, value| options[:only].include?(attribute) } if options[:only]
|
32
|
+
self.create(
|
33
|
+
:user => object.user,
|
34
|
+
:eventable => object,
|
35
|
+
:verb => verb,
|
36
|
+
:change_data => changed_data.symbolize_keys
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
def find_all_by_eventable object
|
41
|
+
where :eventable_id => object.id, :eventable_type => object.class.name
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Eventifier
|
4
|
+
module EventObserverMixin
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
include do
|
8
|
+
observe Eventifier::Event
|
9
|
+
end
|
10
|
+
|
11
|
+
module InstanceMethods
|
12
|
+
def add_notification klass_name, relation, method
|
13
|
+
observed_classes.each do |observed_class|
|
14
|
+
notification_mappings[klass_name.name] ||= { }
|
15
|
+
notification_mappings[klass_name.name][method] = relation
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def after_create event
|
20
|
+
Rails.logger.info "Firing #{event.eventable_type}##{event.verb} - #{notification_mappings[event.eventable_type][event.verb]}" if notification_mappings.has_key?(event.eventable_type) and notification_mappings[event.eventable_type].has_key?(event.verb) and defined?(Rails)
|
21
|
+
|
22
|
+
method_from_relation(event.eventable, notification_mappings[event.eventable_type][event.verb]).each do |user|
|
23
|
+
next if user == event.user
|
24
|
+
Eventifier::Notification.create event: event, user: user
|
25
|
+
end if notification_mappings.has_key?(event.eventable_type) and notification_mappings[event.eventable_type].has_key?(event.verb)
|
26
|
+
end
|
27
|
+
|
28
|
+
def method_from_relation object, relation
|
29
|
+
if relation.kind_of?(Hash)
|
30
|
+
method_from_relation(proc { |object, method| object.send(method) }.call(object, relation.keys.first), relation.values.first)
|
31
|
+
else
|
32
|
+
send_to = proc { |object, method| object.send(method) }.call(object, relation)
|
33
|
+
send_to = send_to.kind_of?(Array) ? send_to : [send_to]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def notification_mappings
|
40
|
+
@notification_mapppings ||= { }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -1,20 +1,20 @@
|
|
1
1
|
module Eventifier
|
2
2
|
module EventTracking
|
3
3
|
def events_for(klass, *args, &block)
|
4
|
-
|
4
|
+
@klasses = klass.kind_of?(Array) ? klass : [klass]
|
5
5
|
|
6
|
-
|
6
|
+
options = args[0] || { }
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
methods = options.delete(:track_on)
|
9
|
+
attributes = options.delete(:attributes)
|
10
10
|
|
11
|
-
|
11
|
+
create_observers
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
if block.nil?
|
14
|
+
track_on methods, :attributes => attributes
|
15
|
+
else
|
16
|
+
instance_eval(&block)
|
17
|
+
end
|
18
18
|
end
|
19
19
|
|
20
20
|
def create_observers
|
@@ -24,24 +24,24 @@ module Eventifier
|
|
24
24
|
# If the observer doesn't exist, create the class
|
25
25
|
unless self.class.const_defined?("#{target_klass}Observer")
|
26
26
|
constant_name = "#{target_klass}Observer"
|
27
|
-
klass
|
27
|
+
klass = Class.new(OBSERVER_CLASS)
|
28
28
|
self.class.qualified_const_set(constant_name, klass)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
def track_on methods, options = {}
|
34
|
-
methods
|
33
|
+
def track_on methods, options = { }
|
34
|
+
methods = methods.kind_of?(Array) ? methods : [methods]
|
35
35
|
attributes = options.delete(:attributes)
|
36
36
|
raise 'No events defined to track' if methods.compact.empty?
|
37
|
-
User.class_eval { has_many :notifications, :class_name => Eventifier::Notification } unless User.respond_to?(:notifications)
|
37
|
+
User.class_eval { has_many :notifications, :class_name => 'Eventifier::Notification' } unless User.respond_to?(:notifications)
|
38
38
|
Eventifier::EventObserver.instance
|
39
39
|
|
40
40
|
# set up each class with an observer and relationships
|
41
41
|
@klasses.each do |target_klass|
|
42
42
|
# Add relations to class
|
43
|
-
target_klass.class_eval { has_many :events, :as => :eventable, :class_name => Eventifier::Event, :dependent => :destroy }
|
44
|
-
target_klass
|
43
|
+
target_klass.class_eval { has_many :events, :as => :eventable, :class_name => 'Eventifier::Event', :dependent => :destroy }
|
44
|
+
add_notification_association(target_klass)
|
45
45
|
|
46
46
|
# create an observer and have it observe the class
|
47
47
|
klass = self.class.const_get("#{target_klass}Observer")
|
@@ -67,8 +67,8 @@ module Eventifier
|
|
67
67
|
relation = args.delete_at(0) if args.length == 2
|
68
68
|
args = args.first
|
69
69
|
|
70
|
-
methods
|
71
|
-
methods
|
70
|
+
methods = args.delete(:on)
|
71
|
+
methods = methods.kind_of?(Array) ? methods : [methods]
|
72
72
|
relation ||= args
|
73
73
|
|
74
74
|
@klasses.each do |target_klass|
|
@@ -77,5 +77,16 @@ module Eventifier
|
|
77
77
|
end
|
78
78
|
end
|
79
79
|
end
|
80
|
+
|
81
|
+
def url url_proc
|
82
|
+
@klasses.each do |target_klass|
|
83
|
+
Eventifier::EventTracking.url_mappings[target_klass.name.underscore.to_sym] = url_proc
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.url_mappings
|
88
|
+
@url_mapppings ||= {}
|
89
|
+
end
|
90
|
+
|
80
91
|
end
|
81
92
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Eventifier
|
2
|
+
module GhostMixin
|
3
|
+
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
|
8
|
+
validates :ghost_class, :presence => true
|
9
|
+
validates :ghost_id, :presence => true
|
10
|
+
validates :data_hash, :presence => true
|
11
|
+
end
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
def create_from_object object
|
15
|
+
create :ghost_class => object.class.name, :ghost_id => object.id, :data_hash => object.serializable_hash
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def ghost
|
20
|
+
klass = Object.const_get(ghost_class)
|
21
|
+
ghost_object = klass.new data_hash
|
22
|
+
ghost_object.id = ghost_id
|
23
|
+
|
24
|
+
ghost_object
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -13,6 +13,8 @@ module Eventifier
|
|
13
13
|
replace_text = "<strong class='target'>#{replace_text}</strong>"
|
14
14
|
when "{{object.title}}"
|
15
15
|
replace_text = "<strong class='target'>#{replace_text}</strong>"
|
16
|
+
when "{{user.name}}"
|
17
|
+
replace_text = "<strong class='user'>#{replace_text}</strong>"
|
16
18
|
else
|
17
19
|
replace_text = "<strong>#{replace_text}</strong>"
|
18
20
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'eventifier/event_mixin'
|
2
|
+
|
3
|
+
module Eventifier
|
4
|
+
class Event
|
5
|
+
include Mongoid::Document
|
6
|
+
include Mongoid::Timestamps
|
7
|
+
include Eventifier::EventMixin
|
8
|
+
|
9
|
+
field :change_data, :type => Hash
|
10
|
+
field :eventable_type, :type => String
|
11
|
+
field :verb, :type => Symbol
|
12
|
+
|
13
|
+
index({ user_id: 1 })
|
14
|
+
index({ eventable_id: 1, eventable_type: 1 })
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Eventifier
|
2
|
+
module EventTracking
|
3
|
+
OBSERVER_CLASS = Mongoid::Observer
|
4
|
+
|
5
|
+
def add_notification_association target_klass
|
6
|
+
target_klass.class_eval do
|
7
|
+
define_method :notifications do
|
8
|
+
events.map(&:notifications).flatten.compact
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'eventifier/ghost_mixin'
|
2
|
+
|
3
|
+
module Eventifier
|
4
|
+
class Ghost
|
5
|
+
include Mongoid::Document
|
6
|
+
include Mongoid::Timestamps
|
7
|
+
include Eventifier::GhostMixin
|
8
|
+
|
9
|
+
field :ghost_id, :type => BSON::ObjectId
|
10
|
+
field :ghost_class, :type => String
|
11
|
+
field :data_hash, :type => Hash
|
12
|
+
|
13
|
+
index({ ghost_class: 1, ghost_id: 1 })
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'eventifier/notification_mixin'
|
2
|
+
|
3
|
+
module Eventifier
|
4
|
+
class Notification
|
5
|
+
include Mongoid::Document
|
6
|
+
include Mongoid::Timestamps
|
7
|
+
include Eventifier::NotificationMixin
|
8
|
+
|
9
|
+
default_scope order_by([:created_at, :desc])
|
10
|
+
scope :for_events, ->(ids) { where(event_id: ids) }
|
11
|
+
scope :for_user, ->(user) { where(user_id: user.id) }
|
12
|
+
scope :since, ->(date) { where(:created_at.gt => date) }
|
13
|
+
scope :latest, order_by([:created_at, :desc]).limit(5)
|
14
|
+
|
15
|
+
index({ user_id: 1 })
|
16
|
+
index({ event_id: 1 })
|
17
|
+
#index({ parent_id: 1})
|
18
|
+
end
|
19
|
+
end
|
@@ -13,31 +13,22 @@ module Eventifier
|
|
13
13
|
# %li= notification_message notification.event
|
14
14
|
|
15
15
|
def notification_message event
|
16
|
+
default = "notifications.default.#{event.verb}".to_sym
|
16
17
|
if event.verb.to_sym == :update
|
17
18
|
if event.change_data.keys.count == 1
|
18
|
-
key = "notifications.#{event.eventable_type.downcase}.#{event.verb}.
|
19
|
+
key = "notifications.#{event.eventable_type.downcase}.#{event.verb}.attributes.#{event.change_data.keys.first}"
|
20
|
+
default = ["notifications.#{event.eventable_type.downcase}.#{event.verb}.single".to_sym, default]
|
19
21
|
else
|
20
22
|
key = "notifications.#{event.eventable_type.downcase}.#{event.verb}.multiple"
|
21
23
|
end
|
22
24
|
else
|
23
25
|
key = "notifications.#{event.eventable_type.downcase}.#{event.verb}"
|
24
26
|
end
|
25
|
-
message = I18n.translate key, :default =>
|
27
|
+
message = I18n.translate key, :default => default, "user.name" => event.user.name, :"event.type" => event.eventable_type
|
26
28
|
|
27
29
|
replace_vars(message, event).html_safe
|
28
30
|
end
|
29
31
|
|
30
|
-
# Generating where the notification should lead when clicked
|
31
|
-
|
32
|
-
def notification_url eventable
|
33
|
-
case eventable.class.name.downcase.to_sym
|
34
|
-
when :activity
|
35
|
-
url_for([eventable.group, eventable])
|
36
|
-
when :announcement
|
37
|
-
url_for([eventable.group, eventable.activity])
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
32
|
def self.included(base)
|
42
33
|
base.helper_method :notification_message, :notification_url
|
43
34
|
end
|
@@ -7,7 +7,11 @@ module Eventifier
|
|
7
7
|
|
8
8
|
def notification_email(notification)
|
9
9
|
@notification = notification
|
10
|
-
@notification_url =
|
10
|
+
@notification_url = if Eventifier::EventTracking.url_mappings[notification.event.eventable_type.underscore.to_sym]
|
11
|
+
main_app.url_for Eventifier::EventTracking.url_mappings[notification.event.eventable_type.underscore.to_sym].call(notification.event.eventable)
|
12
|
+
else
|
13
|
+
main_app.url_for notification.event.eventable
|
14
|
+
end
|
11
15
|
@notification_message = notification_message(notification.event)
|
12
16
|
|
13
17
|
mail :to => notification.user.email,
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Eventifier
|
4
|
+
|
5
|
+
module NotificationMixin
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
belongs_to :event, :class_name => 'Eventifier::Event'
|
10
|
+
belongs_to :user
|
11
|
+
|
12
|
+
validates :event, :presence => true
|
13
|
+
validates :user, :presence => true
|
14
|
+
validates :event_id, :uniqueness => { :scope => :user_id }
|
15
|
+
|
16
|
+
after_create :send_email
|
17
|
+
end
|
18
|
+
|
19
|
+
module ClassMethods
|
20
|
+
def expire_for_past_events!(time_limit = 1.day.ago)
|
21
|
+
self.for_events(Event.expired_ids(time_limit)).each &:expire!
|
22
|
+
end
|
23
|
+
|
24
|
+
def unread_for(user)
|
25
|
+
if user.notifications_last_read_at
|
26
|
+
for_user(user).since(user.notifications_last_read_at)
|
27
|
+
else
|
28
|
+
for_user(user)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def unread_for?(user)
|
34
|
+
return true if user.notifications_last_read_at.nil?
|
35
|
+
created_at > user.notifications_last_read_at
|
36
|
+
end
|
37
|
+
|
38
|
+
def send_email
|
39
|
+
Eventifier::NotificationMailer.notification_email(self).deliver
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/eventifier/version.rb
CHANGED