user_notification 0.0.1

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 (59) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +3 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.md +1 -0
  5. data/Rakefile +18 -0
  6. data/lib/generators/user_notification/migration/migration_generator.rb +17 -0
  7. data/lib/generators/user_notification/migration/templates/migration.rb +24 -0
  8. data/lib/generators/user_notification/notification/notification_generator.rb +17 -0
  9. data/lib/generators/user_notification/notification/templates/notification.rb +3 -0
  10. data/lib/generators/user_notification.rb +14 -0
  11. data/lib/user_notification/actions/creation.rb +15 -0
  12. data/lib/user_notification/actions/destruction.rb +15 -0
  13. data/lib/user_notification/actions/update.rb +15 -0
  14. data/lib/user_notification/activity.rb +6 -0
  15. data/lib/user_notification/common.rb +342 -0
  16. data/lib/user_notification/config.rb +63 -0
  17. data/lib/user_notification/models/activist.rb +9 -0
  18. data/lib/user_notification/models/adapter.rb +5 -0
  19. data/lib/user_notification/models/notification.rb +13 -0
  20. data/lib/user_notification/models/trackable.rb +9 -0
  21. data/lib/user_notification/orm/active_record/activist.rb +48 -0
  22. data/lib/user_notification/orm/active_record/adapter.rb +16 -0
  23. data/lib/user_notification/orm/active_record/notification.rb +24 -0
  24. data/lib/user_notification/orm/active_record/trackable.rb +15 -0
  25. data/lib/user_notification/orm/active_record.rb +5 -0
  26. data/lib/user_notification/orm/mongo_mapper/activist.rb +46 -0
  27. data/lib/user_notification/orm/mongo_mapper/adapter.rb +12 -0
  28. data/lib/user_notification/orm/mongo_mapper/notification.rb +33 -0
  29. data/lib/user_notification/orm/mongo_mapper/trackable.rb +11 -0
  30. data/lib/user_notification/orm/mongo_mapper.rb +4 -0
  31. data/lib/user_notification/orm/mongoid/activist.rb +45 -0
  32. data/lib/user_notification/orm/mongoid/adapter.rb +12 -0
  33. data/lib/user_notification/orm/mongoid/notification.rb +26 -0
  34. data/lib/user_notification/orm/mongoid/trackable.rb +11 -0
  35. data/lib/user_notification/orm/mongoid.rb +4 -0
  36. data/lib/user_notification/renderable.rb +118 -0
  37. data/lib/user_notification/roles/deactivatable.rb +42 -0
  38. data/lib/user_notification/roles/tracked.rb +183 -0
  39. data/lib/user_notification/utility/store_controller.rb +37 -0
  40. data/lib/user_notification/utility/view_helpers.rb +26 -0
  41. data/lib/user_notification/version.rb +4 -0
  42. data/lib/user_notification.rb +68 -0
  43. data/test/migrations/001_create_notifications.rb +24 -0
  44. data/test/migrations/002_create_articles.rb +11 -0
  45. data/test/migrations/003_create_users.rb +8 -0
  46. data/test/migrations/004_add_nonstandard_to_notifications.rb +7 -0
  47. data/test/mongo_mapper.yml +4 -0
  48. data/test/mongoid.yml +6 -0
  49. data/test/test_activist.rb +56 -0
  50. data/test/test_common.rb +168 -0
  51. data/test/test_controller_integration.rb +41 -0
  52. data/test/test_generators.rb +30 -0
  53. data/test/test_helper.rb +124 -0
  54. data/test/test_notification.rb +67 -0
  55. data/test/test_tracking.rb +378 -0
  56. data/test/test_view_helpers.rb +36 -0
  57. data/test/views/layouts/_notification.erb +1 -0
  58. data/test/views/user_notification/_test.erb +8 -0
  59. metadata +260 -0
@@ -0,0 +1,48 @@
1
+ module UserNotification
2
+ module ORM
3
+ module ActiveRecord
4
+ # Module extending classes that serve as owners
5
+ module Activist
6
+ extend ActiveSupport::Concern
7
+
8
+ # Loads the {ClassMethods#activist} method for declaring the class
9
+ # as an activist.
10
+ def self.extended(base)
11
+ base.extend(ClassMethods)
12
+ end
13
+
14
+
15
+ # Module extending classes that serve as owners
16
+ module ClassMethods
17
+ # Adds ActiveRecord associations to model to simplify fetching
18
+ # so you can list notifications performed by the owner.
19
+ # It is completely optional. Any model can be an owner to an notification
20
+ # even without being an explicit activist.
21
+ #
22
+ # == Usage:
23
+ # In model:
24
+ #
25
+ # class User < ActiveRecord::Base
26
+ # include UserNotification::Model
27
+ # activist
28
+ # end
29
+ #
30
+ # In controller:
31
+ # User.first.notifications
32
+ #
33
+ def activist
34
+ # Association of notifications as their owner.
35
+ # @!method notifications_as_owner
36
+ # @return [Array<Notification>] Activities which self is the owner of.
37
+ has_many :notifications_as_owner, :class_name => "::UserNotification::Notification", :as => :owner
38
+
39
+ # Association of notifications as their recipient.
40
+ # @!method notifications_as_recipient
41
+ # @return [Array<Notification>] Activities which self is the recipient of.
42
+ has_many :notifications_as_recipient, :class_name => "::UserNotification::Notification", :as => :recipient
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,16 @@
1
+ module UserNotification
2
+ module ORM
3
+ # Support for ActiveRecord for UserNotification. Used by default and supported
4
+ # officialy.
5
+ module ActiveRecord
6
+ # Provides ActiveRecord specific, database-related routines for use by
7
+ # UserNotification.
8
+ class Adapter
9
+ # Creates the notification on `trackable` with `options`
10
+ def self.create_notification(trackable, options)
11
+ trackable.notifications.create options
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,24 @@
1
+ module UserNotification
2
+ module ORM
3
+ module ActiveRecord
4
+ # The ActiveRecord model containing
5
+ # details about recorded notification.
6
+ class Notification < ::ActiveRecord::Base
7
+ include Renderable
8
+
9
+ # Define polymorphic association to the parent
10
+ belongs_to :trackable, :polymorphic => true
11
+ # Define ownership to a resource responsible for this notification
12
+ belongs_to :owner, :polymorphic => true
13
+ # Define ownership to a resource targeted by this notification
14
+ belongs_to :recipient, :polymorphic => true
15
+ # Serialize parameters Hash
16
+ serialize :parameters, Hash
17
+
18
+ if ::ActiveRecord::VERSION::MAJOR < 4
19
+ attr_accessible :key, :owner, :parameters, :recipient, :trackable
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,15 @@
1
+ module UserNotification
2
+ module ORM
3
+ module ActiveRecord
4
+ # Implements {UserNotification::Trackable} for ActiveRecord
5
+ # @see UserNotification::Trackable
6
+ module Trackable
7
+ # Creates an association for notifications where self is the *trackable*
8
+ # object.
9
+ def self.extended(base)
10
+ base.has_many :notifications, :class_name => "::UserNotification::Notification", :as => :trackable
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ require 'active_record'
2
+ require_relative 'active_record/notification.rb'
3
+ require_relative 'active_record/adapter.rb'
4
+ require_relative 'active_record/activist.rb'
5
+ require_relative 'active_record/trackable.rb'
@@ -0,0 +1,46 @@
1
+ module UserNotification
2
+ module ORM
3
+ module MongoMapper
4
+ # Module extending classes that serve as owners
5
+ module Activist
6
+ extend ActiveSupport::Concern
7
+
8
+ def self.extended(base)
9
+ base.extend(ClassMethods)
10
+ end
11
+ # Association of notifications as their owner.
12
+ # @!method notifications
13
+ # @return [Array<Notification>] Activities which self is the owner of.
14
+
15
+ # Association of notifications as their recipient.
16
+ # @!method private_notifications
17
+ # @return [Array<Notification>] Activities which self is the recipient of.
18
+
19
+ # Module extending classes that serve as owners
20
+ module ClassMethods
21
+ # Adds MongoMapper associations to model to simplify fetching
22
+ # so you can list notifications performed by the owner.
23
+ # It is completely optional. Any model can be an owner to an notification
24
+ # even without being an explicit activist.
25
+ #
26
+ # == Usage:
27
+ # In model:
28
+ #
29
+ # class User
30
+ # include MongoMapper::Document
31
+ # include UserNotification::Model
32
+ # activist
33
+ # end
34
+ #
35
+ # In controller:
36
+ # User.first.notifications
37
+ #
38
+ def activist
39
+ many :notifications_as_owner, :class_name => "::UserNotification::Notification", :as => :owner
40
+ many :notifications_as_recipient, :class_name => "::UserNotification::Notification", :as => :recipient
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,12 @@
1
+ module UserNotification
2
+ module ORM
3
+ module MongoMapper
4
+ class Adapter
5
+ # Creates the notification on `trackable` with `options`
6
+ def self.create_notification(trackable, options)
7
+ trackable.notifications.create options
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,33 @@
1
+ require 'mongo_mapper'
2
+ require 'active_support/core_ext'
3
+
4
+ module UserNotification
5
+ module ORM
6
+ module MongoMapper
7
+ # The MongoMapper document containing
8
+ # details about recorded notification.
9
+ class Notification
10
+ include ::MongoMapper::Document
11
+ include Renderable
12
+
13
+ class SymbolHash < Hash
14
+ def self.from_mongo(value)
15
+ value.symbolize_keys unless value.nil?
16
+ end
17
+ end
18
+
19
+ # Define polymorphic association to the parent
20
+ belongs_to :trackable, polymorphic: true
21
+ # Define ownership to a resource responsible for this notification
22
+ belongs_to :owner, polymorphic: true
23
+ # Define ownership to a resource targeted by this notification
24
+ belongs_to :recipient, polymorphic: true
25
+
26
+ key :key, String
27
+ key :parameters, SymbolHash
28
+
29
+ timestamps!
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,11 @@
1
+ module UserNotification
2
+ module ORM
3
+ module MongoMapper
4
+ module Trackable
5
+ def self.extended(base)
6
+ base.many :notifications, :class_name => "::UserNotification::Notification", order: :created_at.asc, :as => :trackable
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ require_relative "mongo_mapper/notification.rb"
2
+ require_relative "mongo_mapper/adapter.rb"
3
+ require_relative "mongo_mapper/activist.rb"
4
+ require_relative "mongo_mapper/trackable.rb"
@@ -0,0 +1,45 @@
1
+ module UserNotification
2
+ module ORM
3
+ module Mongoid
4
+ # Module extending classes that serve as owners
5
+ module Activist
6
+ extend ActiveSupport::Concern
7
+
8
+ def self.extended(base)
9
+ base.extend(ClassMethods)
10
+ end
11
+ # Association of notifications as their owner.
12
+ # @!method notifications
13
+ # @return [Array<Notification>] Activities which self is the owner of.
14
+
15
+ # Association of notifications as their recipient.
16
+ # @!method private_notifications
17
+ # @return [Array<Notification>] Activities which self is the recipient of.
18
+
19
+ # Module extending classes that serve as owners
20
+ module ClassMethods
21
+ # Adds ActiveRecord associations to model to simplify fetching
22
+ # so you can list notifications performed by the owner.
23
+ # It is completely optional. Any model can be an owner to an notification
24
+ # even without being an explicit activist.
25
+ #
26
+ # == Usage:
27
+ # In model:
28
+ #
29
+ # class User < ActiveRecord::Base
30
+ # include UserNotification::Model
31
+ # activist
32
+ # end
33
+ #
34
+ # In controller:
35
+ # User.first.notifications
36
+ #
37
+ def activist
38
+ has_many :notifications_as_owner, :class_name => "::UserNotification::Notification", :inverse_of => :owner
39
+ has_many :notifications_as_recipient, :class_name => "::UserNotification::Notification", :inverse_of => :recipient
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,12 @@
1
+ module UserNotification
2
+ module ORM
3
+ module Mongoid
4
+ class Adapter
5
+ # Creates the notification on `trackable` with `options`
6
+ def self.create_notification(trackable, options)
7
+ trackable.notifications.create options
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,26 @@
1
+ require 'mongoid'
2
+
3
+ module UserNotification
4
+ module ORM
5
+ module Mongoid
6
+ # The ActiveRecord model containing
7
+ # details about recorded notification.
8
+ class Notification
9
+ include ::Mongoid::Document
10
+ include ::Mongoid::Timestamps
11
+ include ::Mongoid::Attributes::Dynamic if (::Mongoid::VERSION =~ /^4/) == 0
12
+ include Renderable
13
+
14
+ # Define polymorphic association to the parent
15
+ belongs_to :trackable, polymorphic: true
16
+ # Define ownership to a resource responsible for this notification
17
+ belongs_to :owner, polymorphic: true
18
+ # Define ownership to a resource targeted by this notification
19
+ belongs_to :recipient, polymorphic: true
20
+
21
+ field :key, type: String
22
+ field :parameters, type: Hash
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,11 @@
1
+ module UserNotification
2
+ module ORM
3
+ module Mongoid
4
+ module Trackable
5
+ def self.extended(base)
6
+ base.has_many :notifications, :class_name => "::UserNotification::Notification", :as => :trackable
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ require_relative "mongoid/notification.rb"
2
+ require_relative "mongoid/adapter.rb"
3
+ require_relative "mongoid/activist.rb"
4
+ require_relative "mongoid/trackable.rb"
@@ -0,0 +1,118 @@
1
+ module UserNotification
2
+ # Provides logic for rendering notifications. Handles both i18n strings
3
+ # support and smart partials rendering (different templates per notification key).
4
+ module Renderable
5
+ # Virtual attribute returning text description of the notification
6
+ # using the notification's key to translate using i18n.
7
+ def text(params = {})
8
+ # TODO: some helper for key transformation for two supported formats
9
+ k = key.split('.')
10
+ k.unshift('notification') if k.first != 'notification'
11
+ k = k.join('.')
12
+
13
+ I18n.t(k, parameters.merge(params) || {})
14
+ end
15
+
16
+ # Renders notification from views.
17
+ #
18
+ # @param [ActionView::Base] context
19
+ # @return [nil] nil
20
+ #
21
+ # Renders notification to the given ActionView context with included
22
+ # AV::Helpers::RenderingHelper (most commonly just ActionView::Base)
23
+ #
24
+ # The *preferred* *way* of rendering notifications is
25
+ # to provide a template specifying how the rendering should be happening.
26
+ # However, one may choose using _I18n_ based approach when developing
27
+ # an application that supports plenty of languages.
28
+ #
29
+ # If partial view exists that matches the *key* attribute
30
+ # renders that partial with local variables set to contain both
31
+ # Notification and notification_parameters (hash with indifferent access)
32
+ #
33
+ # Otherwise, it outputs the I18n translation to the context
34
+ # @example Render a list of all notifications from a view (erb)
35
+ # <ul>
36
+ # <% for notification in UserNotification::Notification.all %>
37
+ # <li><%= render_notification(notification) %></li>
38
+ # <% end %>
39
+ # </ul>
40
+ #
41
+ # = Layouts
42
+ # You can supply a layout that will be used for notification partials
43
+ # with :layout param.
44
+ # Keep in mind that layouts for partials are also partials.
45
+ # @example Supply a layout
46
+ # # in views:
47
+ # # All examples look for a layout in app/views/layouts/_notification.erb
48
+ # render_notification @notification, :layout => "notification"
49
+ # render_notification @notification, :layout => "layouts/notification"
50
+ # render_notification @notification, :layout => :notification
51
+ #
52
+ # # app/views/layouts/_notification.erb
53
+ # <p><%= a.created_at %></p>
54
+ # <%= yield %>
55
+ #
56
+ # = Creating a template
57
+ # To use templates for formatting how the notification should render,
58
+ # create a template based on notification key, for example:
59
+ #
60
+ # Given a key _notification.article.create_, create directory tree
61
+ # _app/views/user_notification/article/_ and create the _create_ partial there
62
+ #
63
+ # Note that if a key consists of more than three parts splitted by commas, your
64
+ # directory structure will have to be deeper, for example:
65
+ # notification.article.comments.destroy => app/views/user_notification/articles/comments/_destroy.html.erb
66
+ #
67
+ # == Variables in templates
68
+ # From within a template there are two variables at your disposal:
69
+ # * notification (aliased as *a* for a shortcut)
70
+ # * params (aliased as *p*) [converted into a HashWithIndifferentAccess]
71
+ #
72
+ # @example Template for key: _notification.article.create_ (erb)
73
+ # <p>
74
+ # Article <strong><%= p[:name] %></strong>
75
+ # was written by <em><%= p["author"] %></em>
76
+ # <%= distance_of_time_in_words_to_now(a.created_at) %>
77
+ # </p>
78
+ def render(context, params = {})
79
+ partial_path = nil
80
+ if params.has_key? :display
81
+ # if i18n has been requested, let it render and bail
82
+ return context.render :text => self.text(params) if params[:display].to_sym == :"i18n"
83
+ partial_path = 'user_notification/'+params[:display].to_s
84
+ end
85
+
86
+ controller = UserNotification.get_controller
87
+ if layout = params.delete(:layout)
88
+ layout = layout.to_s
89
+ layout = layout[0,8] == "layouts/" ? layout : "layouts/#{layout}"
90
+ end
91
+
92
+ locals = params.delete(:locals) || Hash.new
93
+
94
+ params_indifferent = self.parameters.with_indifferent_access
95
+ params_indifferent.merge!(params)
96
+
97
+ context.render :partial => (partial_path || self.template_path(self.key)),
98
+ :layout => layout,
99
+ :locals => locals.merge(:a => self, :notification => self,
100
+ :controller => controller,
101
+ :current_user => controller.respond_to?(:current_user) ?
102
+ controller.current_user : nil ,
103
+ :p => params_indifferent, :params => params_indifferent)
104
+ end
105
+
106
+ protected
107
+ # Builds the path to template based on notification key
108
+ # TODO: verify that attribute `key` is splitted by commas
109
+ # and that the word before first comma is equal to
110
+ # "notification"
111
+ def template_path(key)
112
+ path = key.split(".")
113
+ path.delete_at(0) if path[0] == "notification"
114
+ path.unshift "user_notification"
115
+ path.join("/")
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,42 @@
1
+ module UserNotification
2
+ # Enables per-class disabling of UserNotification functionality.
3
+ module Deactivatable
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ class_attribute :user_notification_enabled_for_model
8
+ set_user_notification_class_defaults
9
+ end
10
+
11
+ # Returns true if UserNotification is enabled
12
+ # globally and for this class.
13
+ # @return [Boolean]
14
+ # @api private
15
+ # @since 0.5.0
16
+ # overrides the method from Common
17
+ def user_notification_enabled?
18
+ UserNotification.enabled? && self.class.user_notification_enabled_for_model
19
+ end
20
+
21
+ # Provides global methods to disable or enable UserNotification on a per-class
22
+ # basis.
23
+ module ClassMethods
24
+ # Switches user_notification off for this class
25
+ def user_notification_off
26
+ self.user_notification_enabled_for_model = false
27
+ end
28
+
29
+ # Switches user_notification on for this class
30
+ def user_notification_on
31
+ self.user_notification_enabled_for_model = true
32
+ end
33
+
34
+ # @since 1.0.0
35
+ # @api private
36
+ def set_user_notification_class_defaults
37
+ super
38
+ self.user_notification_enabled_for_model = true
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,183 @@
1
+ module UserNotification
2
+ # Main module extending classes we want to keep track of.
3
+ module Tracked
4
+ extend ActiveSupport::Concern
5
+ # A shortcut method for setting custom key, owner and parameters of {Notification}
6
+ # in one line. Accepts a hash with 3 keys:
7
+ # :key, :owner, :params. You can specify all of them or just the ones you want to overwrite.
8
+ #
9
+ # == Options
10
+ #
11
+ # [:key]
12
+ # See {Common#notification_key}
13
+ # [:owner]
14
+ # See {Common#notification_owner}
15
+ # [:params]
16
+ # See {Common#notification_params}
17
+ # [:recipient]
18
+ # Set the recipient for this notification. Useful for private notifications, which should only be visible to a certain user. See {Common#notification_recipient}.
19
+ # @example
20
+ #
21
+ # @article = Article.new
22
+ # @article.title = "New article"
23
+ # @article.notification :key => "my.custom.article.key", :owner => @article.author, :params => {:title => @article.title}
24
+ # @article.save
25
+ # @article.notifications.last.key #=> "my.custom.article.key"
26
+ # @article.notifications.last.parameters #=> {:title => "New article"}
27
+ #
28
+ # @param options [Hash] instance options to set on the tracked model
29
+ # @return [nil]
30
+ def notification(options = {})
31
+ rest = options.clone
32
+ self.notification_key = rest.delete(:key) if rest[:key]
33
+ self.notification_owner = rest.delete(:owner) if rest[:owner]
34
+ self.notification_params = rest.delete(:params) if rest[:params]
35
+ self.notification_recipient = rest.delete(:recipient) if rest[:recipient]
36
+ self.notification_custom_fields = rest if rest.count > 0
37
+ nil
38
+ end
39
+
40
+ # Module with basic +tracked+ method that enables tracking models.
41
+ module ClassMethods
42
+ # Adds required callbacks for creating and updating
43
+ # tracked models and adds +notifications+ relation for listing
44
+ # associated notifications.
45
+ #
46
+ # == Parameters:
47
+ # [:owner]
48
+ # Specify the owner of the {Notification} (person responsible for the action).
49
+ # It can be a Proc, Symbol or an ActiveRecord object:
50
+ # == Examples:
51
+ #
52
+ # tracked :owner => :author
53
+ # tracked :owner => proc {|o| o.author}
54
+ #
55
+ # Keep in mind that owner relation is polymorphic, so you can't just
56
+ # provide id number of the owner object.
57
+ # [:recipient]
58
+ # Specify the recipient of the {Notification}
59
+ # It can be a Proc, Symbol, or an ActiveRecord object
60
+ # == Examples:
61
+ #
62
+ # tracked :recipient => :author
63
+ # tracked :recipient => proc {|o| o.author}
64
+ #
65
+ # Keep in mind that recipient relation is polymorphic, so you can't just
66
+ # provide id number of the owner object.
67
+ # [:params]
68
+ # Accepts a Hash with custom parameters you want to pass to i18n.translate
69
+ # method. It is later used in {Renderable#text} method.
70
+ # == Example:
71
+ # class Article < ActiveRecord::Base
72
+ # include UserNotification::Model
73
+ # tracked :params => {
74
+ # :title => :title,
75
+ # :author_name => "Michael",
76
+ # :category_name => proc {|controller, model_instance| model_instance.category.name},
77
+ # :summary => proc {|controller, model_instance| truncate(model.text, :length => 30)}
78
+ # }
79
+ # end
80
+ #
81
+ # Values in the :params hash can either be an *exact* *value*, a *Proc/Lambda* executed before saving the notification or a *Symbol*
82
+ # which is a an attribute or a method name executed on the tracked model's instance.
83
+ #
84
+ # Everything specified here has a lower priority than parameters
85
+ # specified directly in {#notification} method.
86
+ # So treat it as a place where you provide 'default' values or where you
87
+ # specify what data should be gathered for every notification.
88
+ # For more dynamic settings refer to {Notification} model documentation.
89
+ # [:skip_defaults]
90
+ # Disables recording of notifications on create/update/destroy leaving that to programmer's choice. Check {UserNotification::Common#create_notification}
91
+ # for a guide on how to manually record notifications.
92
+ # [:only]
93
+ # Accepts a symbol or an array of symbols, of which any combination of the three is accepted:
94
+ # * _:create_
95
+ # * _:update_
96
+ # * _:destroy_
97
+ # Selecting one or more of these will make UserNotification create notifications
98
+ # automatically for the tracked model on selected actions.
99
+ #
100
+ # Resulting notifications will have have keys assigned to, respectively:
101
+ # * _article.create_
102
+ # * _article.update_
103
+ # * _article.destroy_
104
+ # Since only three options are valid,
105
+ # see _:except_ option for a shorter version
106
+ # [:except]
107
+ # Accepts a symbol or an array of symbols with values like in _:only_, above.
108
+ # Values provided will be subtracted from all default actions:
109
+ # (create, update, destroy).
110
+ #
111
+ # So, passing _create_ would track and automatically create
112
+ # notifications on _update_ and _destroy_ actions,
113
+ # but not on the _create_ action.
114
+ # [:on]
115
+ # Accepts a Hash with key being the *action* on which to execute *value* (proc)
116
+ # Currently supported only for CRUD actions which are enabled in _:only_
117
+ # or _:except_ options on this method.
118
+ #
119
+ # Key-value pairs in this option define callbacks that can decide
120
+ # whether to create an notification or not. Procs have two attributes for
121
+ # use: _model_ and _controller_. If the proc returns true, the notification
122
+ # will be created, if not, then notification will not be saved.
123
+ #
124
+ # == Example:
125
+ # # app/models/article.rb
126
+ # tracked :on => {:update => proc {|model, controller| model.published? }}
127
+ #
128
+ # In the example above, given a model Article with boolean column _published_.
129
+ # The notifications with key _article.update_ will only be created
130
+ # if the published status is set to true on that article.
131
+ # @param opts [Hash] options
132
+ # @return [nil] options
133
+ def tracked(opts = {})
134
+ options = opts.clone
135
+
136
+ all_options = [:create, :update, :destroy]
137
+
138
+ if !options.has_key?(:skip_defaults) && !options[:only] && !options[:except]
139
+ include Creation
140
+ include Destruction
141
+ include Update
142
+ end
143
+ options.delete(:skip_defaults)
144
+
145
+ if options[:except]
146
+ options[:only] = all_options - Array(options.delete(:except))
147
+ end
148
+
149
+ if options[:only]
150
+ Array(options[:only]).each do |opt|
151
+ if opt.eql?(:create)
152
+ include Creation
153
+ elsif opt.eql?(:destroy)
154
+ include Destruction
155
+ elsif opt.eql?(:update)
156
+ include Update
157
+ end
158
+ end
159
+ options.delete(:only)
160
+ end
161
+
162
+ if options[:owner]
163
+ self.notification_owner_global = options.delete(:owner)
164
+ end
165
+ if options[:recipient]
166
+ self.notification_recipient_global = options.delete(:recipient)
167
+ end
168
+ if options[:params]
169
+ self.notification_params_global = options.delete(:params)
170
+ end
171
+ if options.has_key?(:on) and options[:on].is_a? Hash
172
+ self.notification_hooks = options.delete(:on).select {|_, v| v.is_a? Proc}.symbolize_keys
173
+ end
174
+
175
+ options.each do |k, v|
176
+ self.notification_custom_fields_global[k] = v
177
+ end
178
+
179
+ nil
180
+ end
181
+ end
182
+ end
183
+ end