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