eventifier 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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