eventifier 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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