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.
Files changed (52) hide show
  1. data/.gitignore +2 -1
  2. data/.travis.yml +14 -0
  3. data/Gemfile.lock +17 -3
  4. data/README.textile +7 -2
  5. data/Rakefile +1 -8
  6. data/eventifier.gemspec +7 -3
  7. data/lib/eventifier/active_record/event.rb +9 -0
  8. data/lib/eventifier/active_record/event_observer.rb +8 -0
  9. data/lib/eventifier/active_record/event_tracking.rb +11 -0
  10. data/lib/eventifier/active_record/ghost.rb +9 -0
  11. data/lib/eventifier/active_record/notification.rb +13 -0
  12. data/lib/eventifier/active_record_support.rb +5 -0
  13. data/lib/eventifier/event_mixin.rb +45 -0
  14. data/lib/eventifier/event_observer_mixin.rb +44 -0
  15. data/lib/eventifier/event_tracking.rb +29 -18
  16. data/lib/eventifier/ghost_mixin.rb +27 -0
  17. data/lib/eventifier/helper_methods.rb +2 -0
  18. data/lib/eventifier/mongoid/event.rb +16 -0
  19. data/lib/eventifier/mongoid/event_observer.rb +7 -0
  20. data/lib/eventifier/mongoid/event_tracking.rb +13 -0
  21. data/lib/eventifier/mongoid/ghost.rb +15 -0
  22. data/lib/eventifier/mongoid/notification.rb +19 -0
  23. data/lib/eventifier/mongoid/user_patch.rb +3 -0
  24. data/lib/eventifier/mongoid_support.rb +6 -0
  25. data/lib/eventifier/notification_helper.rb +4 -13
  26. data/lib/eventifier/notification_mailer.rb +5 -1
  27. data/lib/eventifier/notification_mixin.rb +42 -0
  28. data/lib/eventifier/version.rb +1 -1
  29. data/lib/eventifier.rb +8 -10
  30. data/lib/generators/eventifier/install/install_generator.rb +1 -1
  31. data/spec/event_helper_spec.rb +45 -35
  32. data/spec/event_observer_spec.rb +1 -6
  33. data/spec/event_spec.rb +16 -5
  34. data/spec/event_tracking_spec.rb +20 -0
  35. data/spec/eventifier_spec.rb +48 -52
  36. data/spec/fabricators/fabricator.rb +31 -0
  37. data/spec/ghost_spec.rb +30 -0
  38. data/spec/helper_methods_spec.rb +2 -2
  39. data/spec/integration/eventifier_spec.rb +85 -44
  40. data/spec/notification_helper_spec.rb +13 -6
  41. data/spec/notification_mailer_spec.rb +6 -1
  42. data/spec/notification_spec.rb +9 -11
  43. data/spec/spec_helper.rb +11 -2
  44. data/spec/support/database_cleaner.rb +3 -0
  45. data/spec/support/model_helpers.rb +36 -0
  46. data/spec/{support → test_classes}/active_record_support.rb +9 -0
  47. data/spec/test_classes/mongoid_support.rb +34 -0
  48. metadata +94 -24
  49. data/lib/eventifier/event.rb +0 -35
  50. data/lib/eventifier/event_observer.rb +0 -35
  51. data/lib/eventifier/notification.rb +0 -40
  52. data/spec/support/blueprints.rb +0 -24
data/.gitignore CHANGED
@@ -1,2 +1,3 @@
1
1
  *.gem
2
- tmp
2
+ tmp
3
+ .idea/*
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.1)
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
- machinist
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
- RSpec::Core::RakeTask.new(:rcov) do |spec|
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 "machinist"
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,9 @@
1
+ require 'eventifier/event_mixin'
2
+
3
+ module Eventifier
4
+ class Event < ActiveRecord::Base
5
+ include Eventifier::EventMixin
6
+
7
+ serialize :change_data
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ require 'eventifier/event_observer_mixin'
2
+
3
+ module Eventifier
4
+ class EventObserver < ActiveRecord::Observer
5
+ include Eventifier::EventObserverMixin
6
+
7
+ end
8
+ 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,9 @@
1
+ require 'eventifier/ghost_mixin'
2
+
3
+ module Eventifier
4
+ class Ghost < ActiveRecord::Base
5
+ include Eventifier::GhostMixin
6
+
7
+ serialize :data_hash
8
+ end
9
+ 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,5 @@
1
+ require 'eventifier/active_record/event_tracking'
2
+ require 'eventifier/active_record/event'
3
+ require 'eventifier/active_record/notification'
4
+ require 'eventifier/active_record/event_observer'
5
+ require 'eventifier/active_record/ghost'
@@ -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
- @klasses = klass.kind_of?(Array) ? klass : [klass]
4
+ @klasses = klass.kind_of?(Array) ? klass : [klass]
5
5
 
6
- options = args[0] || {}
6
+ options = args[0] || { }
7
7
 
8
- methods = options.delete(:track_on)
9
- attributes = options.delete(:attributes)
8
+ methods = options.delete(:track_on)
9
+ attributes = options.delete(:attributes)
10
10
 
11
- create_observers
11
+ create_observers
12
12
 
13
- if block.nil?
14
- track_on methods, :attributes => attributes
15
- else
16
- instance_eval(&block)
17
- end
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 = Class.new(ActiveRecord::Observer)
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 = methods.kind_of?(Array) ? methods : [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.class_eval { has_many :notifications, :through => :events, :class_name => Eventifier::Notification, :dependent => :destroy }
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 = args.delete(:on)
71
- methods = methods.kind_of?(Array) ? methods : [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,7 @@
1
+ require 'eventifier/event_observer_mixin'
2
+
3
+ module Eventifier
4
+ class EventObserver < Mongoid::Observer
5
+ include Eventifier::EventObserverMixin
6
+ end
7
+ 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
@@ -0,0 +1,3 @@
1
+ class User
2
+ field :notifications_last_read_at, :type => DateTime
3
+ end
@@ -0,0 +1,6 @@
1
+ require 'eventifier/mongoid/event_tracking'
2
+ require 'eventifier/mongoid/user_patch'
3
+ require 'eventifier/mongoid/event'
4
+ require 'eventifier/mongoid/notification'
5
+ require 'eventifier/mongoid/event_observer'
6
+ require 'eventifier/mongoid/ghost'
@@ -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}.single"
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 => :"notifications.default.#{event.verb}", "user.name" => event.user.name, :"event.type" => event.eventable_type
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 = notification_url(notification.event.eventable)
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
@@ -1,3 +1,3 @@
1
1
  module Eventifier
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end