activity_notification 0.0.8

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 (104) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +56 -0
  4. data/.rspec +3 -0
  5. data/.travis.yml +28 -0
  6. data/Gemfile +8 -0
  7. data/Gemfile.lock +174 -0
  8. data/MIT-LICENSE +20 -0
  9. data/README.md +437 -0
  10. data/Rakefile +19 -0
  11. data/activity_notification.gemspec +33 -0
  12. data/app/controllers/activity_notification/notifications_controller.rb +119 -0
  13. data/app/controllers/activity_notification/notifications_with_devise_controller.rb +29 -0
  14. data/app/mailers/activity_notification/mailer.rb +13 -0
  15. data/app/views/activity_notification/mailer/default/default.html.erb +7 -0
  16. data/app/views/activity_notification/notifications/default/_default.html.erb +36 -0
  17. data/app/views/activity_notification/notifications/default/_index.html.erb +9 -0
  18. data/app/views/activity_notification/notifications/default/destroy.js.erb +2 -0
  19. data/app/views/activity_notification/notifications/default/index.html.erb +17 -0
  20. data/app/views/activity_notification/notifications/default/open.js.erb +2 -0
  21. data/app/views/activity_notification/notifications/default/open_all.js.erb +2 -0
  22. data/app/views/activity_notification/notifications/default/show.html.erb +2 -0
  23. data/config/locales/en.yml +8 -0
  24. data/lib/activity_notification.rb +52 -0
  25. data/lib/activity_notification/apis/notification_api.rb +147 -0
  26. data/lib/activity_notification/common.rb +86 -0
  27. data/lib/activity_notification/config.rb +23 -0
  28. data/lib/activity_notification/controllers/store_controller.rb +30 -0
  29. data/lib/activity_notification/helpers/polymorphic_helpers.rb +32 -0
  30. data/lib/activity_notification/helpers/view_helpers.rb +108 -0
  31. data/lib/activity_notification/mailers/helpers.rb +97 -0
  32. data/lib/activity_notification/models/notifiable.rb +136 -0
  33. data/lib/activity_notification/models/notification.rb +50 -0
  34. data/lib/activity_notification/models/notifier.rb +11 -0
  35. data/lib/activity_notification/models/target.rb +104 -0
  36. data/lib/activity_notification/rails.rb +6 -0
  37. data/lib/activity_notification/rails/routes.rb +105 -0
  38. data/lib/activity_notification/renderable.rb +142 -0
  39. data/lib/activity_notification/roles/acts_as_notifiable.rb +37 -0
  40. data/lib/activity_notification/roles/acts_as_target.rb +30 -0
  41. data/lib/activity_notification/version.rb +3 -0
  42. data/lib/generators/activity_notification/controllers_generator.rb +44 -0
  43. data/lib/generators/activity_notification/install_generator.rb +45 -0
  44. data/lib/generators/activity_notification/migration/migration_generator.rb +17 -0
  45. data/lib/generators/activity_notification/notification/notification_generator.rb +17 -0
  46. data/lib/generators/activity_notification/views_generator.rb +44 -0
  47. data/lib/generators/templates/README +53 -0
  48. data/lib/generators/templates/active_record/migration.rb +18 -0
  49. data/lib/generators/templates/activity_notification.rb +18 -0
  50. data/lib/generators/templates/controllers/README +13 -0
  51. data/lib/generators/templates/controllers/notifications_controller.rb +66 -0
  52. data/lib/generators/templates/controllers/notifications_with_devise_controller.rb +74 -0
  53. data/lib/generators/templates/notification/notification.rb +3 -0
  54. data/lib/tasks/activity_notification_tasks.rake +4 -0
  55. data/spec/concerns/notification_api_spec.rb +531 -0
  56. data/spec/factories/articles.rb +5 -0
  57. data/spec/factories/comments.rb +6 -0
  58. data/spec/factories/notifications.rb +7 -0
  59. data/spec/factories/users.rb +5 -0
  60. data/spec/models/notification_spec.rb +259 -0
  61. data/spec/rails_app/Rakefile +6 -0
  62. data/spec/rails_app/app/controllers/application_controller.rb +5 -0
  63. data/spec/rails_app/app/controllers/concerns/.keep +0 -0
  64. data/spec/rails_app/app/helpers/application_helper.rb +2 -0
  65. data/spec/rails_app/app/mailers/.keep +0 -0
  66. data/spec/rails_app/app/models/.keep +0 -0
  67. data/spec/rails_app/app/models/article.rb +12 -0
  68. data/spec/rails_app/app/models/comment.rb +18 -0
  69. data/spec/rails_app/app/models/concerns/.keep +0 -0
  70. data/spec/rails_app/app/models/user.rb +8 -0
  71. data/spec/rails_app/app/views/layouts/application.html.erb +14 -0
  72. data/spec/rails_app/bin/bundle +3 -0
  73. data/spec/rails_app/bin/rails +4 -0
  74. data/spec/rails_app/bin/rake +4 -0
  75. data/spec/rails_app/bin/setup +29 -0
  76. data/spec/rails_app/config.ru +4 -0
  77. data/spec/rails_app/config/application.rb +20 -0
  78. data/spec/rails_app/config/boot.rb +5 -0
  79. data/spec/rails_app/config/database.yml +25 -0
  80. data/spec/rails_app/config/environment.rb +12 -0
  81. data/spec/rails_app/config/environments/development.rb +44 -0
  82. data/spec/rails_app/config/environments/production.rb +79 -0
  83. data/spec/rails_app/config/environments/test.rb +45 -0
  84. data/spec/rails_app/config/initializers/activity_notification.rb +18 -0
  85. data/spec/rails_app/config/initializers/assets.rb +11 -0
  86. data/spec/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  87. data/spec/rails_app/config/initializers/cookies_serializer.rb +3 -0
  88. data/spec/rails_app/config/initializers/devise.rb +274 -0
  89. data/spec/rails_app/config/initializers/filter_parameter_logging.rb +4 -0
  90. data/spec/rails_app/config/initializers/inflections.rb +16 -0
  91. data/spec/rails_app/config/initializers/mime_types.rb +4 -0
  92. data/spec/rails_app/config/initializers/session_store.rb +3 -0
  93. data/spec/rails_app/config/initializers/wrap_parameters.rb +14 -0
  94. data/spec/rails_app/config/routes.rb +5 -0
  95. data/spec/rails_app/config/secrets.yml +22 -0
  96. data/spec/rails_app/db/migrate/20160715050420_create_notifications.rb +18 -0
  97. data/spec/rails_app/db/migrate/20160715050433_create_test_tables.rb +36 -0
  98. data/spec/rails_app/db/schema.rb +73 -0
  99. data/spec/rails_app/public/404.html +67 -0
  100. data/spec/rails_app/public/422.html +67 -0
  101. data/spec/rails_app/public/500.html +66 -0
  102. data/spec/rails_app/public/favicon.ico +0 -0
  103. data/spec/spec_helper.rb +34 -0
  104. metadata +309 -0
@@ -0,0 +1,50 @@
1
+ module ActivityNotification
2
+ class Notification < ActiveRecord::Base
3
+ include Renderable
4
+ include Common
5
+ include NotificationApi
6
+ self.table_name = ActivityNotification.config.table_name
7
+
8
+ belongs_to :target, polymorphic: true
9
+ belongs_to :notifiable, polymorphic: true
10
+ belongs_to :group, polymorphic: true
11
+ belongs_to :group_owner, class_name: :Notification
12
+ has_many :group_members,
13
+ class_name: "::ActivityNotification::Notification",
14
+ foreign_key: :group_owner_id
15
+ belongs_to :notifier, polymorphic: true
16
+
17
+ # Serialize parameters Hash
18
+ serialize :parameters, Hash
19
+
20
+ validates :target, presence: true
21
+ validates :notifiable, presence: true
22
+ validates :key, presence: true
23
+
24
+ scope :group_owners_only, -> { where(group_owner_id: nil) }
25
+ scope :group_members_only, -> { where.not(group_owner_id: nil) }
26
+ scope :unopened_only, -> { where(opened_at: nil) }
27
+ scope :unopened_index, -> { unopened_only.group_owners_only.latest_order }
28
+ scope :opened_only!, -> { where.not(opened_at: nil) }
29
+ scope :opened_only, ->(limit) { opened_only!.limit(limit) }
30
+ scope :opened_index, ->(limit) { opened_only(limit).group_owners_only.latest_order }
31
+ scope :unopened_index_group_members_only, -> { where(group_owner_id: unopened_index.pluck(:id)) }
32
+ scope :opened_index_group_members_only, ->(limit) { where(group_owner_id: opened_index(limit).pluck(:id)) }
33
+
34
+ scope :filtered_by_target, ->(target) { where(target: target) }
35
+ scope :filtered_by_instance, ->(notifiable) { where(notifiable: notifiable) }
36
+ scope :filtered_by_type, ->(notifiable_type) { where(notifiable_type: notifiable_type) }
37
+ scope :filtered_by_group, ->(group) { where(group: group) }
38
+ scope :filtered_by_key, ->(key) { where(key: key) }
39
+
40
+ scope :with_target, -> { includes(:target) }
41
+ scope :with_notifiable, -> { includes(:notifiable) }
42
+ scope :with_group, -> { includes(:group) }
43
+ scope :with_notifier, -> { includes(:notifier) }
44
+
45
+ scope :latest_order, -> { order(created_at: :desc) }
46
+ scope :earliest_order, -> { order(created_at: :asc) }
47
+ scope :latest, -> { latest_order.first }
48
+ scope :earliest, -> { earliest_order.first }
49
+ end
50
+ end
@@ -0,0 +1,11 @@
1
+ module ActivityNotification
2
+ module Notifier
3
+ extend ActiveSupport::Concern
4
+ included do
5
+ include Common
6
+ has_many :sent_notifications,
7
+ class_name: "::ActivityNotification::Notification",
8
+ as: :notifier
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,104 @@
1
+ module ActivityNotification
2
+ module Target
3
+ extend ActiveSupport::Concern
4
+ included do
5
+ include Common
6
+ include ActsAsTarget
7
+ has_many :notifications,
8
+ class_name: "::ActivityNotification::Notification",
9
+ as: :target
10
+ class_attribute :_notification_email, :_notification_email_allowed
11
+ set_target_class_defaults
12
+ end
13
+
14
+ class_methods do
15
+ def set_target_class_defaults
16
+ self._notification_email = nil
17
+ self._notification_email_allowed = false
18
+ end
19
+ end
20
+
21
+ def mailer_to
22
+ resolve_value(_notification_email)
23
+ end
24
+
25
+ def notification_email_allowed?(notifiable, key)
26
+ resolve_value(_notification_email_allowed, notifiable, key)
27
+ end
28
+
29
+ def unopened_notification_count
30
+ unopened_notification_index.count
31
+ end
32
+
33
+ def has_unopened_notifications?
34
+ unopened_notification_index.exists?
35
+ end
36
+
37
+ #TODO is this switching the best solution?
38
+ def notification_index(limit = nil)
39
+ # When the target have unopened notifications
40
+ notifications.unopened_index.exists? ?
41
+ # Return unopened notifications
42
+ unopened_notification_index(limit) :
43
+ # Otherwise, return opened notifications
44
+ limit.present? ?
45
+ opened_notification_index(limit) :
46
+ opened_notification_index
47
+ end
48
+
49
+ def unopened_notification_index(limit = nil)
50
+ limit.present? ?
51
+ notifications.unopened_index.limit(limit) :
52
+ notifications.unopened_index
53
+ end
54
+
55
+ def opened_notification_index(limit = ActivityNotification.config.opened_limit)
56
+ notifications.opened_index(limit)
57
+ end
58
+
59
+
60
+ # Wrapper methods of SimpleNotify class methods
61
+
62
+ def notify_to(notifiable, options = {})
63
+ Notification.notify_to(self, notifiable, options)
64
+ end
65
+
66
+ def open_all_notifications(opened_at = nil)
67
+ Notification.open_all_of(self, opened_at)
68
+ end
69
+
70
+ # Methods to be overriden
71
+
72
+ # Typical method to get notifications index
73
+ def notification_index_with_attributes(limit = nil)
74
+ # When the target have unopened notifications
75
+ unopened_notification_index.exists? ?
76
+ # Return unopened notifications
77
+ unopened_notification_index_with_attributes(limit) :
78
+ # Otherwise, return opened notifications
79
+ limit.present? ?
80
+ opened_notification_index_with_attributes(limit) :
81
+ opened_notification_index_with_attributes
82
+ end
83
+
84
+ def unopened_notification_index_with_attributes(limit = nil)
85
+ Notification.group_member_exists?(unopened_notification_index(limit)) ?
86
+ unopened_notification_index(limit).with_target.with_notifiable.with_group.with_notifier :
87
+ unopened_notification_index(limit).with_target.with_notifiable.with_notifier
88
+ end
89
+
90
+ def opened_notification_index_with_attributes(limit = ActivityNotification.config.opened_limit)
91
+ Notification.group_member_exists?(opened_notification_index(limit)) ?
92
+ opened_notification_index(limit).with_target.with_notifiable.with_group.with_notifier :
93
+ opened_notification_index(limit).with_target.with_notifiable.with_notifier
94
+ end
95
+
96
+ def authenticate_with_devise?(current_resource)
97
+ unless current_resource.instance_of? self.class
98
+ raise TypeError, "Defferent type of devise resource #{current_resource.class.to_s} has been passed to #{self.class}##{__method__}. You have to override #{self.class}##{__method__} method."
99
+ end
100
+ current_resource == self
101
+ end
102
+
103
+ end
104
+ end
@@ -0,0 +1,6 @@
1
+ require 'activity_notification/rails/routes'
2
+
3
+ module ActivityNotification #:nodoc:
4
+ class Engine < ::Rails::Engine #:nodoc:
5
+ end
6
+ end
@@ -0,0 +1,105 @@
1
+ require "active_support/core_ext/object/try"
2
+ require "active_support/core_ext/hash/slice"
3
+
4
+ module ActionDispatch::Routing
5
+ class Mapper
6
+ # Includes notify_to method for routes.
7
+ # This method is responsible to generate all needed routes for activity_notification
8
+ #
9
+ # ==== Examples
10
+ #
11
+ # notify_to :users
12
+ # notify_to :users, with_devise: :users
13
+ # notify_to :users, with_devise: :users, only: [:open, :open_all, :move]
14
+ #
15
+ # When you have an User model configured as a target (e.g. defined acts_as_target),
16
+ # you can creat this inside your routes:
17
+ #
18
+ # notify_to :users
19
+ #
20
+ # This method creates the needed routes:
21
+ #
22
+ # # Notification routes
23
+ # user_notifications GET /users/:user_id/notifications(.:format)
24
+ # {controller:"activity_notification/notifications", action:"index", target_type:"users"}
25
+ # user_notification GET /users/:user_id/notifications/:id(.:format)
26
+ # {controller:"activity_notification/notifications", action:"show", target_type:"users"}
27
+ # user_notification DELETE /users/:user_id/notifications/:id(.:format)
28
+ # {controller:"activity_notification/notifications", action:"destroy", target_type:"users"}
29
+ # open_all_user_notifications POST /users/:user_id/notifications/open_all(.:format)
30
+ # {controller:"activity_notification/notifications", action:"open_all", target_type:"users"}
31
+ # move_user_notification POST /users/:user_id/notifications/:id/move(.:format)
32
+ # {controller:"activity_notification/notifications", action:"move", target_type:"users"}
33
+ # open_user_notification POST /users/:user_id/notifications/:id/open(.:format)
34
+ # {controller:"activity_notification/notifications", action:"open", target_type:"users"}
35
+ #
36
+ # When you use devise for authentication and you want make notification target assciated with devise,
37
+ # you can creat this inside your routes:
38
+ #
39
+ # notify_to :users, with_devise: true
40
+ #
41
+ # This with_devise option creates the needed routes assciated with devise authentication:
42
+ #
43
+ # # Notification with devise routes
44
+ # user_notifications GET /users/:user_id/notifications(.:format)
45
+ # {controller:"activity_notification/notifications_with_devise", action:"index", devise_type:"users", target_type:"users"}
46
+ # user_notification GET /users/:user_id/notifications/:id(.:format)
47
+ # {controller:"activity_notification/notifications_with_devise", action:"show", devise_type:"users", target_type:"users"}
48
+ # user_notification DELETE /users/:user_id/notifications/:id(.:format)
49
+ # {controller:"activity_notification/notifications_with_devise", action:"destroy", devise_type:"users", target_type:"users"}
50
+ # open_all_user_notifications POST /users/:user_id/notifications/open_all(.:format)
51
+ # {controller:"activity_notification/notifications_with_devise", action:"open_all", devise_type:"users", target_type:"users"}
52
+ # move_user_notification POST /users/:user_id/notifications/:id/move(.:format)
53
+ # {controller:"activity_notification/notifications_with_devise", action:"move", devise_type:"users", target_type:"users"}
54
+ # open_user_notification POST /users/:user_id/notifications/:id/open(.:format)
55
+ # {controller:"activity_notification/notifications_with_devise", action:"open", devise_type:"users", target_type:"users"}
56
+ #
57
+ # ==== Options
58
+ #TODO add document for options
59
+ #
60
+ def notify_to(*resources)
61
+ options = resources.extract_options!
62
+
63
+ #TODO check resources if it includes target module
64
+
65
+ if (with_devise = options.delete(:with_devise)).present?
66
+ options[:controller] ||= "activity_notification/notifications_with_devise"
67
+ options[:as] ||= "notifications"
68
+ #TODO check device configuration in model
69
+ devise_defaults = { devise_type: with_devise.to_s }
70
+ else
71
+ options[:controller] ||= "activity_notification/notifications"
72
+ end
73
+ options[:except] ||= []
74
+ options[:except].concat( [:new, :create, :edit, :update] )
75
+
76
+ #TODO other options
77
+ # :as, :path_prefix, :path_names ...
78
+
79
+ resources.each do |resource|
80
+ self.resources resource, only: :none do
81
+ options[:defaults] = (devise_defaults || {}).merge({ target_type: resource.to_s })
82
+ self.resources :notifications, options do
83
+ collection do
84
+ post :open_all unless ignore_path?(:open_all, options)
85
+ end
86
+ member do
87
+ get :move unless ignore_path?(:move, options)
88
+ post :open unless ignore_path?(:open, options)
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ end
95
+
96
+ private
97
+
98
+ def ignore_path?(action, options)
99
+ return true if options[:except].present? and options[:except].include?(action)
100
+ return true if options[:only].present? and not options[:only].include?(action)
101
+ false
102
+ end
103
+
104
+ end
105
+ end
@@ -0,0 +1,142 @@
1
+ module ActivityNotification
2
+ # Provides logic for rendering notifications.
3
+ # Handles both i18n strings support and smart partials rendering (different templates per notification key).
4
+ # Deeply uses PublicActivity as reference
5
+ module Renderable
6
+ # Virtual attribute returning text description of the notification
7
+ # using the notification's key to translate using i18n.
8
+ def text(params = {})
9
+ k = key.split('.')
10
+ k.unshift('notification') if k.first != 'notification'
11
+ if params.has_key?(:target)
12
+ k.insert(1, params[:target])
13
+ else
14
+ k.insert(1, target.to_resource_name)
15
+ end
16
+ k = k.join('.')
17
+
18
+ I18n.t(k, parameters.merge(params) || {})
19
+ end
20
+
21
+ # Renders notification from views.
22
+ #
23
+ # @param [ActionView::Base] context
24
+ # @return [nil] nil
25
+ #
26
+ # The preferred way of rendering notifications is
27
+ # to provide a template specifying how the rendering should be happening.
28
+ # However, you can choose using _I18n_ based approach when developing
29
+ # an application that supports plenty of languages.
30
+ #
31
+ # If partial view exists that matches the "key" attribute
32
+ # renders that partial with local variables set to contain both
33
+ # Activity and activity_parameters (hash with indifferent access).
34
+ #
35
+ # If the partial view does not exist and you wish to fallback to rendering
36
+ # through the I18n translation, you can do so by passing in a :fallback
37
+ # parameter whose value equals :text.
38
+ #
39
+ # If you do not want to define a partial view, and instead want to have
40
+ # all missing views fallback to a default, you can define the :fallback
41
+ # value equal to the partial you wish to use when the partial defined
42
+ # by the notification key does not exist.
43
+ #
44
+ # @example Render a list of all @target's notifications of from a view (erb)
45
+ # <ul>
46
+ # <% @target.notifications.each do |notification| %>
47
+ # <li><%= render_notification(notification) %></li>
48
+ # <% end %>
49
+ # </ul>
50
+ #
51
+ # @example Fallback to the I18n text translation if the view is missing
52
+ # <ul>
53
+ # <% @target.notifications.each do |notification| %>
54
+ # <li><%= render_notification(notification, fallback: :text) %></li>
55
+ # <% end %>
56
+ # </ul>
57
+ #
58
+ # @example Fallback to a default view if the view for the current notification key is missing.
59
+ # The string is the partial name you wish to use.
60
+ # <ul>
61
+ # <% @target.notifications.each do |notification| %>
62
+ # <li><%= render_notification(notification, fallback: 'default') %></li>
63
+ # <% end %>
64
+ # </ul>
65
+ #
66
+ # # Layouts
67
+ #TODO
68
+ #
69
+ # # Creating a template
70
+ #
71
+ # To use templates for formatting how the notification should render,
72
+ # create a template based on target type and notification key, for example:
73
+ #
74
+ # Given a target type users and key _notification.article.create_, create directory tree
75
+ # _app/views/activity_notifications/users/article/_ and create the _create_ partial there
76
+ #
77
+ # Note that if a key consists of more than three parts splitted by commas, your
78
+ # directory structure will have to be deeper, for example:
79
+ # notification.article.comments.destroy => app/views/activity_notifications/users/articles/comments/_destroy.html.erb
80
+ #
81
+ # ## Custom Directory
82
+ #TODO
83
+ #
84
+ # ## Variables in templates
85
+ #TODO
86
+ def render(context, params = {})
87
+ params[:i18n] and return context.render text: self.text(params)
88
+
89
+ partial = partial_path(*params.values_at(:partial, :partial_root, :target))
90
+ layout = layout_path(*params.values_at(:layout, :layout_root))
91
+ locals = prepare_locals(params)
92
+
93
+ begin
94
+ context.render params.merge(partial: partial, layout: layout, locals: locals)
95
+ rescue ActionView::MissingTemplate => e
96
+ if params[:fallback] == :text
97
+ context.render text: self.text(params)
98
+ elsif params[:fallback].present?
99
+ partial = partial_path(*params.values_at(:fallback, :partial_root, :target))
100
+ context.render params.merge(partial: partial, layout: layout, locals: locals)
101
+ else
102
+ raise e
103
+ end
104
+ end
105
+ end
106
+
107
+ def partial_path(path = nil, root = nil, target = nil)
108
+ controller = ActivityNotification.get_controller if ActivityNotification.respond_to?(:get_controller)
109
+ root ||= "activity_notification/notifications/#{target}" if target.present?
110
+ root ||= controller.target_view_path if controller.present? and controller.respond_to?(:target_view_path)
111
+ root ||= 'activity_notification/notifications/default'
112
+ path ||= self.key.gsub('.', '/')
113
+ select_path(path, root)
114
+ end
115
+
116
+ def layout_path(path = nil, root = nil)
117
+ path.nil? and return
118
+ root ||= 'layouts'
119
+ select_path(path, root)
120
+ end
121
+
122
+ def prepare_locals(params)
123
+ locals = params.delete(:locals) || {}
124
+
125
+ prepared_parameters = prepare_parameters(params)
126
+ locals.merge\
127
+ notification: self,
128
+ parameters: prepared_parameters
129
+ end
130
+
131
+ def prepare_parameters(params)
132
+ @prepared_params ||= self.parameters.with_indifferent_access.merge(params)
133
+ end
134
+
135
+ private
136
+
137
+ def select_path(path, root)
138
+ [root, path].map(&:to_s).join('/')
139
+ end
140
+
141
+ end
142
+ end
@@ -0,0 +1,37 @@
1
+ module ActivityNotification
2
+ module ActsAsNotifiable
3
+ extend ActiveSupport::Concern
4
+
5
+ class_methods do
6
+ # Adds required callbacks for creating and updating
7
+ # notifiable models.
8
+ #
9
+ # == Parameters:
10
+ # [:targets]
11
+ #TODO
12
+ def acts_as_notifiable(target_type, opts = {})
13
+ options = opts.clone
14
+ assign_globals target_type, options
15
+ nil
16
+ end
17
+
18
+ def available_options
19
+ [:targets, :group, :notifier, :parameters, :email_allowed, :notifiable_path].freeze
20
+ end
21
+
22
+ def assign_globals(target_type, options)
23
+ [:targets, :group, :parameters, :email_allowed].each do |key|
24
+ if options[key]
25
+ self.send("_notification_#{key}".to_sym).store(target_type.to_sym, options.delete(key))
26
+ end
27
+ end
28
+ [:notifier, :notifiable_path].each do |key|
29
+ if options[key]
30
+ self.send("_#{key}".to_sym).store(target_type.to_sym, options.delete(key))
31
+ end
32
+ end
33
+ end
34
+
35
+ end
36
+ end
37
+ end