activity_notification 0.0.10 → 1.0.0

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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +6 -0
  3. data/Gemfile +6 -3
  4. data/Gemfile.lock +74 -58
  5. data/README.md +53 -26
  6. data/activity_notification.gemspec +2 -0
  7. data/app/controllers/activity_notification/notifications_controller.rb +4 -4
  8. data/app/mailers/activity_notification/mailer.rb +9 -3
  9. data/app/views/activity_notification/mailer/default/default.html.erb +9 -4
  10. data/app/views/activity_notification/mailer/default/default.text.erb +10 -0
  11. data/app/views/activity_notification/notifications/default/_default.html.erb +173 -34
  12. data/app/views/activity_notification/notifications/default/_index.html.erb +119 -11
  13. data/app/views/activity_notification/notifications/default/destroy.js.erb +2 -2
  14. data/app/views/activity_notification/notifications/default/index.html.erb +25 -14
  15. data/app/views/activity_notification/notifications/default/open.js.erb +2 -2
  16. data/app/views/activity_notification/notifications/default/open_all.js.erb +2 -2
  17. data/app/views/activity_notification/notifications/default/show.html.erb +1 -1
  18. data/gemfiles/Gemfile.rails-4.2 +0 -2
  19. data/gemfiles/Gemfile.rails-4.2.lock +3 -3
  20. data/gemfiles/Gemfile.rails-5.0 +1 -3
  21. data/lib/activity_notification.rb +10 -9
  22. data/lib/activity_notification/apis/notification_api.rb +108 -14
  23. data/lib/activity_notification/common.rb +11 -2
  24. data/lib/activity_notification/config.rb +13 -13
  25. data/lib/activity_notification/helpers/view_helpers.rb +26 -4
  26. data/lib/activity_notification/mailers/helpers.rb +8 -4
  27. data/lib/activity_notification/models.rb +4 -0
  28. data/lib/activity_notification/models/concerns/group.rb +32 -0
  29. data/lib/activity_notification/models/concerns/notifiable.rb +60 -32
  30. data/lib/activity_notification/models/concerns/notifier.rb +17 -1
  31. data/lib/activity_notification/models/concerns/target.rb +114 -55
  32. data/lib/activity_notification/models/notification.rb +26 -25
  33. data/lib/activity_notification/rails.rb +1 -0
  34. data/lib/activity_notification/renderable.rb +8 -3
  35. data/lib/activity_notification/roles/acts_as_common.rb +28 -0
  36. data/lib/activity_notification/roles/acts_as_group.rb +38 -0
  37. data/lib/activity_notification/roles/acts_as_notifiable.rb +56 -22
  38. data/lib/activity_notification/roles/acts_as_notifier.rb +25 -2
  39. data/lib/activity_notification/roles/acts_as_target.rb +27 -9
  40. data/lib/activity_notification/version.rb +1 -1
  41. data/lib/generators/templates/activity_notification.rb +1 -1
  42. data/spec/concerns/apis/notification_api_spec.rb +361 -2
  43. data/spec/concerns/common_spec.rb +36 -0
  44. data/spec/concerns/models/group_spec.rb +61 -0
  45. data/spec/concerns/models/notifiable_spec.rb +37 -0
  46. data/spec/concerns/models/notifier_spec.rb +48 -0
  47. data/spec/concerns/models/target_spec.rb +81 -31
  48. data/spec/factories/dummy/dummy_group.rb +4 -0
  49. data/spec/helpers/view_helpers_spec.rb +13 -0
  50. data/spec/mailers/mailer_spec.rb +8 -1
  51. data/spec/models/dummy/dummy_group_spec.rb +6 -0
  52. data/spec/rails_app/app/assets/stylesheets/application.css +15 -0
  53. data/spec/rails_app/app/assets/stylesheets/reset.css +85 -0
  54. data/spec/rails_app/app/assets/stylesheets/style.css +244 -0
  55. data/spec/rails_app/app/controllers/articles_controller.rb +1 -1
  56. data/spec/rails_app/app/models/admin.rb +2 -1
  57. data/spec/rails_app/app/models/article.rb +9 -2
  58. data/spec/rails_app/app/models/comment.rb +8 -2
  59. data/spec/rails_app/app/models/dummy/dummy_group.rb +4 -0
  60. data/spec/rails_app/app/models/user.rb +8 -3
  61. data/spec/rails_app/app/views/articles/_form.html.erb +14 -10
  62. data/spec/rails_app/app/views/articles/edit.html.erb +8 -6
  63. data/spec/rails_app/app/views/articles/index.html.erb +59 -67
  64. data/spec/rails_app/app/views/articles/new.html.erb +7 -5
  65. data/spec/rails_app/app/views/articles/show.html.erb +47 -36
  66. data/spec/rails_app/app/views/layouts/_header.html.erb +36 -9
  67. data/spec/rails_app/app/views/layouts/application.html.erb +8 -6
  68. data/spec/rails_app/config/environments/development.rb +9 -0
  69. data/spec/rails_app/config/initializers/activity_notification.rb +1 -1
  70. data/spec/rails_app/db/schema.rb +14 -20
  71. data/spec/rails_app/db/seeds.rb +5 -5
  72. data/spec/rails_app/lib/mailer_previews/mailer_preview.rb +13 -0
  73. data/spec/roles/acts_as_group_spec.rb +32 -0
  74. data/spec/roles/acts_as_notifiable_spec.rb +1 -1
  75. data/spec/roles/acts_as_notifier_spec.rb +15 -0
  76. data/spec/roles/acts_as_target_spec.rb +1 -1
  77. metadata +52 -2
@@ -1,2 +1,2 @@
1
- $("#notification_count").html("<%= @target.unopened_notification_count %>");
2
- $("#notifications").html("<%= escape_javascript( render_notification(@notifications, fallback: "default") ) %>");
1
+ $(".notification_count").html("<span class=\"<%= 'unopened' if @target.has_unopened_notifications? %>\"><%= @target.unopened_notification_count %></span>");
2
+ $("<%= ".notification_#{@notification.id}" %>").html("<%= escape_javascript( render_notification(@notification, fallback: :default) ) %>");
@@ -1,2 +1,2 @@
1
- $("#notification_count").html("<%= @target.unopened_notification_count %>");
2
- $("#notifications").html("<%= escape_javascript( render_notification(@notifications, fallback: "default") ) %>");
1
+ $(".notification_count").html("<span class=\"<%= 'unopened' if @target.has_unopened_notifications? %>\"><%= @target.unopened_notification_count %></span>");
2
+ $(".notifications").html("<%= escape_javascript( render_notification(@notifications, fallback: :default) ) %>");
@@ -1,2 +1,2 @@
1
1
  <h1>Notification for <%= "#{@target.class.to_s.underscore} (#{@target.id})" %></h1>
2
- <%= render_notification(@notification, fallback: "default") %>
2
+ <%= render_notification(@notification, fallback: :default) %>
@@ -3,8 +3,6 @@ source 'https://rubygems.org'
3
3
  gemspec path: '../'
4
4
 
5
5
  gem 'rails', '~> 4.2.0'
6
- gem 'sqlite3'
7
- gem 'jquery-rails'
8
6
 
9
7
  group :test do
10
8
  gem 'ammeter'
@@ -1,9 +1,10 @@
1
1
  PATH
2
2
  remote: ../
3
3
  specs:
4
- activity_notification (0.0.9)
4
+ activity_notification (1.0.0)
5
5
  activerecord (>= 4.2.0)
6
6
  i18n (>= 0.5.0)
7
+ jquery-rails (>= 3.1.1)
7
8
  railties (>= 4.2.0, < 5.1)
8
9
 
9
10
  GEM
@@ -177,11 +178,10 @@ DEPENDENCIES
177
178
  coveralls
178
179
  devise (~> 4.2.0)
179
180
  factory_girl_rails (~> 4.7.0)
180
- jquery-rails
181
181
  rails (~> 4.2.0)
182
182
  rspec-rails (~> 3.5.1)
183
183
  simplecov (~> 0.12.0)
184
- sqlite3
184
+ sqlite3 (~> 1.3.11)
185
185
  timecop
186
186
  yard (~> 0.9.5)
187
187
  yard-activesupport-concern (~> 0.0.1)
@@ -3,12 +3,10 @@ source 'https://rubygems.org'
3
3
  gemspec path: '../'
4
4
 
5
5
  gem 'rails', '~> 5.0.0'
6
- gem 'sqlite3'
7
- gem 'jquery-rails'
8
6
 
9
7
  group :test do
10
- gem 'ammeter'
11
8
  gem 'rails-controller-testing'
9
+ gem 'ammeter'
12
10
  gem 'timecop'
13
11
  gem 'coveralls', require: false
14
12
  end
@@ -11,7 +11,7 @@ module ActivityNotification
11
11
  autoload :Target, 'activity_notification/models/concerns/target'
12
12
  autoload :Notifiable, 'activity_notification/models/concerns/notifiable'
13
13
  autoload :Notifier, 'activity_notification/models/concerns/notifier'
14
- autoload :StoreController, 'activity_notification/controllers/store_controller'
14
+ autoload :Group, 'activity_notification/models/concerns/group'
15
15
  autoload :Common
16
16
  autoload :Config
17
17
  autoload :Renderable
@@ -31,14 +31,14 @@ module ActivityNotification
31
31
  # All available options and their defaults are in the example below:
32
32
  # @example Initializer for Rails
33
33
  # ActivityNotification.configure do |config|
34
- # config.enabled = true
35
- # config.table_name = "notifications"
36
- # config.email_enabled = false
37
- # config.mailer_sender = nil
38
- # config.mailer = 'ActivityNotification::Mailer'
39
- # config.parent_mailer = 'ActionMailer::Base'
40
- # config.parent_controller = 'ApplicationController'
41
- # config.opened_limit = 10
34
+ # config.enabled = true
35
+ # config.table_name = "notifications"
36
+ # config.email_enabled = false
37
+ # config.mailer_sender = nil
38
+ # config.mailer = 'ActivityNotification::Mailer'
39
+ # config.parent_mailer = 'ActionMailer::Base'
40
+ # config.parent_controller = 'ApplicationController'
41
+ # config.opened_index_limit = 10
42
42
  # end
43
43
  def self.configure(&block)
44
44
  yield(config) if block_given?
@@ -49,6 +49,7 @@ end
49
49
  # Load ActivityNotification helpers
50
50
  require 'activity_notification/helpers/polymorphic_helpers'
51
51
  require 'activity_notification/helpers/view_helpers'
52
+ require 'activity_notification/controllers/store_controller'
52
53
 
53
54
  # Load role for models
54
55
  require 'activity_notification/models'
@@ -78,7 +78,7 @@ module ActivityNotification
78
78
  # Store notification
79
79
  notification = store_notification(target, notifiable, options)
80
80
  # Send notification email
81
- notification.send_notification_email(send_later) if send_email
81
+ notification.send_notification_email({ send_later: send_later }) if send_email
82
82
  # Return created notification
83
83
  notification
84
84
  end
@@ -92,7 +92,7 @@ module ActivityNotification
92
92
  # @option options [Object] :filtered_by_group (nil) Group instance for filter
93
93
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
94
94
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
95
- # @option options [String] :filtered_by_key (nil) Key of the notification for filter
95
+ # @option options [String] :filtered_by_key (nil) Key of the notification for filter
96
96
  # @return [Integer] Number of opened notification records
97
97
  # @todo Add filter option
98
98
  def open_all_of(target, options = {})
@@ -106,7 +106,7 @@ module ActivityNotification
106
106
  # @param [Array<Notificaion> | ActiveRecord_AssociationRelation<Notificaion>] notifications Array or database query of the notifications to test member exists
107
107
  # @return [Boolean] If group member of the notifications exists
108
108
  def group_member_exists?(notifications)
109
- notifications.present? && where(group_owner_id: notifications.map(&:id)).exists?
109
+ notifications.present? and where(group_owner_id: notifications.map(&:id)).exists?
110
110
  end
111
111
 
112
112
  # Returns available options for kinds of notify methods.
@@ -142,13 +142,16 @@ module ActivityNotification
142
142
 
143
143
  # Sends notification email to the target.
144
144
  #
145
- # @param [Boolean] send_later If it sends notification email asynchronously
145
+ # @param [Hash] options Options for notification email
146
+ # @option send_later [Boolean] :send_later If it sends notification email asynchronously
147
+ # @option options [String, Symbol] :fallback (:default) Fallback template to use when MissingTemplate is raised
146
148
  # @return [Mail::Message, ActionMailer::DeliveryJob] Email message or its delivery job
147
- def send_notification_email(send_later = true)
149
+ def send_notification_email(options = {})
150
+ send_later = options.has_key?(:send_later) ? options[:send_later] : true
148
151
  if send_later
149
- Mailer.send_notification_email(self).deliver_later
152
+ Mailer.send_notification_email(self, options).deliver_later
150
153
  else
151
- Mailer.send_notification_email(self).deliver_now
154
+ Mailer.send_notification_email(self, options).deliver_now
152
155
  end
153
156
  end
154
157
 
@@ -198,26 +201,66 @@ module ActivityNotification
198
201
  #
199
202
  # @param [Integer] limit Limit to query for opened notifications
200
203
  # @return [Boolean] If group member of the notification exists
201
- def group_member_exists?(limit = ActivityNotification.config.opened_limit)
204
+ def group_member_exists?(limit = ActivityNotification.config.opened_index_limit)
202
205
  group_member_count(limit) > 0
203
206
  end
204
207
 
208
+ # Returns if group member notifier except group owner notifier exists.
209
+ # It always returns false if group owner notifier is blank.
210
+ # It counts only the member notifier of the same type with group owner notifier.
211
+ # This method is designed to cache group by query result to avoid N+1 call.
212
+ #
213
+ # @param [Integer] limit Limit to query for opened notifications
214
+ # @return [Boolean] If group member of the notification exists
215
+ def group_member_notifier_exists?(limit = ActivityNotification.config.opened_index_limit)
216
+ group_member_notifier_count(limit) > 0
217
+ end
218
+
205
219
  # Returns count of group members of the notification.
206
220
  # This method is designed to cache group by query result to avoid N+1 call.
207
221
  #
208
222
  # @param [Integer] limit Limit to query for opened notifications
209
223
  # @return [Integer] Count of group members of the notification
210
- def group_member_count(limit = ActivityNotification.config.opened_limit)
224
+ def group_member_count(limit = ActivityNotification.config.opened_index_limit)
225
+ meta_group_member_count(:opened_group_member_count, :unopened_group_member_count, limit)
226
+ end
227
+
228
+ # Returns count of group notifications including owner and members.
229
+ # This method is designed to cache group by query result to avoid N+1 call.
230
+ #
231
+ # @param [Integer] limit Limit to query for opened notifications
232
+ # @return [Integer] Count of group notifications including owner and members
233
+ def group_notification_count(limit = ActivityNotification.config.opened_index_limit)
234
+ group_member_count(limit) + 1
235
+ end
236
+
237
+ # Returns count of group member notifiers of the notification not including group owner notifier.
238
+ # It always returns 0 if group owner notifier is blank.
239
+ # It counts only the member notifier of the same type with group owner notifier.
240
+ # This method is designed to cache group by query result to avoid N+1 call.
241
+ #
242
+ # @param [Integer] limit Limit to query for opened notifications
243
+ # @return [Integer] Count of group member notifiers of the notification
244
+ def group_member_notifier_count(limit = ActivityNotification.config.opened_index_limit)
245
+ meta_group_member_count(:opened_group_member_notifier_count, :unopened_group_member_notifier_count, limit)
246
+ end
247
+
248
+ # Returns count of group member notifiers including group owner notifier.
249
+ # It always returns 0 if group owner notifier is blank.
250
+ # This method is designed to cache group by query result to avoid N+1 call.
251
+ #
252
+ # @param [Integer] limit Limit to query for opened notifications
253
+ # @return [Integer] Count of group notifications including owner and members
254
+ def group_notifier_count(limit = ActivityNotification.config.opened_index_limit)
211
255
  notification = group_member? ? group_owner : self
212
- notification.opened? ?
213
- notification.opened_group_member_count(limit) :
214
- notification.unopened_group_member_count
256
+ notification.notifier.present? ? group_member_notifier_count(limit) + 1 : 0
215
257
  end
216
258
 
217
259
  # Returns notifiable_path to move after opening notification with notifiable.notifiable_path.
218
260
  #
219
261
  # @return [String] Notifiable path URL to move after opening notification
220
262
  def notifiable_path
263
+ notifiable.present? or raise ActiveRecord::RecordNotFound.new("Couldn't find notifiable #{notifiable_type}")
221
264
  notifiable.notifiable_path(target_type, key)
222
265
  end
223
266
 
@@ -237,13 +280,13 @@ module ActivityNotification
237
280
  .count
238
281
  unopened_group_member_counts[id] || 0
239
282
  end
240
-
283
+
241
284
  # Returns count of group members of the opened notification.
242
285
  # This method is designed to cache group by query result to avoid N+1 call.
243
286
  # @api protected
244
287
  #
245
288
  # @return [Integer] Count of group members of the opened notification
246
- def opened_group_member_count(limit = ActivityNotification.config.opened_limit)
289
+ def opened_group_member_count(limit = ActivityNotification.config.opened_index_limit)
247
290
  # Cache group by query result to avoid N+1 call
248
291
  opened_group_member_counts = target.notifications
249
292
  .opened_index_group_members_only(limit)
@@ -252,5 +295,56 @@ module ActivityNotification
252
295
  opened_group_member_counts[id] || 0
253
296
  end
254
297
 
298
+ # Returns count of group member notifiers of the unopened notification not including group owner notifier.
299
+ # This method is designed to cache group by query result to avoid N+1 call.
300
+ # @api protected
301
+ #
302
+ # @return [Integer] Count of group member notifiers of the unopened notification
303
+ def unopened_group_member_notifier_count
304
+ # Cache group by query result to avoid N+1 call
305
+ unopened_group_member_notifier_counts = target.notifications
306
+ .unopened_index_group_members_only
307
+ .includes(:group_owner)
308
+ .where('group_owners_notifications.notifier_type = notifications.notifier_type')
309
+ .where.not('group_owners_notifications.notifier_id = notifications.notifier_id')
310
+ .references(:group_owner)
311
+ .group(:group_owner_id, :notifier_type)
312
+ .count('distinct notifications.notifier_id')
313
+ unopened_group_member_notifier_counts[[id, notifier_type]] || 0
314
+ end
315
+
316
+ # Returns count of group member notifiers of the opened notification not including group owner notifier.
317
+ # This method is designed to cache group by query result to avoid N+1 call.
318
+ # @api protected
319
+ #
320
+ # @return [Integer] Count of group member notifiers of the opened notification
321
+ def opened_group_member_notifier_count(limit = ActivityNotification.config.opened_index_limit)
322
+ # Cache group by query result to avoid N+1 call
323
+ opened_group_member_notifier_counts = target.notifications
324
+ .opened_index_group_members_only(limit)
325
+ .includes(:group_owner)
326
+ .where('group_owners_notifications.notifier_type = notifications.notifier_type')
327
+ .where.not('group_owners_notifications.notifier_id = notifications.notifier_id')
328
+ .references(:group_owner)
329
+ .group(:group_owner_id, :notifier_type)
330
+ .count('distinct notifications.notifier_id')
331
+ opened_group_member_notifier_counts[[id, notifier_type]] || 0
332
+ end
333
+
334
+ # Returns count of various members of the notification.
335
+ # This method is designed to cache group by query result to avoid N+1 call.
336
+ # @api protected
337
+ #
338
+ # @param [Symbol] opened_member_count_method_name Method name to count members of unopened index
339
+ # @param [Symbol] unopened_member_count_method_name Method name to count members of opened index
340
+ # @param [Integer] limit Limit to query for opened notifications
341
+ # @return [Integer] Count of various members of the notification
342
+ def meta_group_member_count(opened_member_count_method_name, unopened_member_count_method_name, limit)
343
+ notification = group_member? ? group_owner : self
344
+ notification.opened? ?
345
+ notification.send(opened_member_count_method_name, limit) :
346
+ notification.send(unopened_member_count_method_name)
347
+ end
348
+
255
349
  end
256
350
  end
@@ -41,6 +41,17 @@ module ActivityNotification
41
41
  end
42
42
  end
43
43
 
44
+ # Casts to indifferent hash
45
+ # @param [ActionController::Parameters, Hash] new_hash
46
+ # @return [HashWithIndifferentAccess] Converted indifferent hash
47
+ def self.cast_to_indifferent_hash(hash = {})
48
+ # This is the typical (not-ActionView::TestCase) code path.
49
+ hash = hash.to_unsafe_h if hash.respond_to?(:to_unsafe_h)
50
+ # In Rails 5 to_unsafe_h returns a HashWithIndifferentAccess, in Rails 4 it returns Hash
51
+ hash = hash.with_indifferent_access if hash.instance_of? Hash
52
+ hash
53
+ end
54
+
44
55
  # Common module included in target and notifiable model.
45
56
  # Provides methods to resolve parameters from configured field or defined method.
46
57
  # Also provides methods to convert into resource name or class name as string.
@@ -109,10 +120,8 @@ module ActivityNotification
109
120
 
110
121
  # Convets to printable model name to show in view or email.
111
122
  # @return [String] Printable model name
112
- # @todo Is this the best to make readable?
113
123
  def printable_name
114
124
  "#{self.printable_type} (#{id})"
115
125
  end
116
-
117
126
  end
118
127
  end
@@ -57,26 +57,26 @@ module ActivityNotification
57
57
  # @return [String] Base controller class for notifications_controller.
58
58
  attr_accessor :parent_controller
59
59
 
60
- # @overload opened_limit
60
+ # @overload opened_index_limit
61
61
  # @return [Integer] Default limit to query for opened notifications.
62
- # @overload opened_limit=(value)
63
- # Sets the opened_limit
64
- # @param [Integer] opened_limit The new opened_limit
62
+ # @overload opened_index_limit=(value)
63
+ # Sets the opened_index_limit
64
+ # @param [Integer] opened_index_limit The new opened_index_limit
65
65
  # @return [Integer] Default limit to query for opened notifications.
66
- attr_accessor :opened_limit
66
+ attr_accessor :opened_index_limit
67
67
 
68
68
  # Initialize configuration for ActivityNotification.
69
69
  # These configuration can be overriden in initializer.
70
70
  # @return [Config] A new instance of Config
71
71
  def initialize
72
- @enabled = true
73
- @table_name = 'notifications'
74
- @email_enabled = false
75
- @mailer_sender = nil
76
- @mailer = 'ActivityNotification::Mailer'
77
- @parent_mailer = 'ActionMailer::Base'
78
- @parent_controller = 'ApplicationController'
79
- @opened_limit = 10
72
+ @enabled = true
73
+ @table_name = 'notifications'
74
+ @email_enabled = false
75
+ @mailer_sender = nil
76
+ @mailer = 'ActivityNotification::Mailer'
77
+ @parent_mailer = 'ActionMailer::Base'
78
+ @parent_controller = 'ApplicationController'
79
+ @opened_index_limit = 10
80
80
  end
81
81
 
82
82
  end
@@ -12,7 +12,7 @@ module ActivityNotification
12
12
  # @option options [String] :partial_root (self.key.gsub('.', '/')) Root path of partial template
13
13
  # @option options [String] :layout (nil) Layout template name
14
14
  # @option options [String] :layout_root ('layouts') Root path of layout template
15
- # @option options [String] :fallback (nil) Fallback template to use when MissingTemplate is raised. Set :text to use i18n text as fallback.
15
+ # @option options [String, Symbol] :fallback (nil) Fallback template to use when MissingTemplate is raised. Set :text to use i18n text as fallback.
16
16
  # @return [String] Rendered view or text as string
17
17
  def render_notification(notifications, options = {})
18
18
  if notifications.is_a? ActivityNotification::Notification
@@ -50,7 +50,7 @@ module ActivityNotification
50
50
  notification_index =
51
51
  case options[:index_content]
52
52
  when :simple then target.notification_index
53
- when :none then target.notifications.none
53
+ when :none then []
54
54
  else target.notification_index_with_attributes
55
55
  end
56
56
  prepare_content_for(target, notification_index, notification_options)
@@ -60,6 +60,17 @@ module ActivityNotification
60
60
  end
61
61
  alias_method :render_notifications_of, :render_notification_of
62
62
 
63
+ # Returns notifications_path for the target
64
+ #
65
+ # @param [Object] target Target instance
66
+ # @param [Hash] params Request parameters
67
+ # @return [String] notifications_path for the target
68
+ # @todo Needs any other better implementation
69
+ # @todo Must handle devise namespace
70
+ def notifications_path_for(target, params = {})
71
+ send("#{target.to_resource_name}_notifications_path", target, params)
72
+ end
73
+
63
74
  # Returns notification_path for the notification
64
75
  #
65
76
  # @param [Notification] notification Notification instance
@@ -93,9 +104,9 @@ module ActivityNotification
93
104
  send("open_#{notification.target.to_resource_name}_notification_path", notification.target, notification, params)
94
105
  end
95
106
 
96
- # Returns open_all_notifications_path for the target of specified notification
107
+ # Returns open_all_notifications_path for the target
97
108
  #
98
- # @param [Notification] notification Notification instance
109
+ # @param [Object] target Target instance
99
110
  # @param [Hash] params Request parameters
100
111
  # @return [String] open_all_notifications_path for the target
101
112
  # @todo Needs any other better implementation
@@ -104,6 +115,17 @@ module ActivityNotification
104
115
  send("open_all_#{target.to_resource_name}_notifications_path", target, params)
105
116
  end
106
117
 
118
+ # Returns notifications_url for the target
119
+ #
120
+ # @param [Object] target Target instance
121
+ # @param [Hash] params Request parameters
122
+ # @return [String] notifications_url for the target
123
+ # @todo Needs any other better implementation
124
+ # @todo Must handle devise namespace
125
+ def notifications_url_for(target, params = {})
126
+ send("#{target.to_resource_name}_notifications_url", target, params)
127
+ end
128
+
107
129
  # Returns notification_url for the target of specified notification
108
130
  #
109
131
  # @param [Notification] notification Notification instance
@@ -17,8 +17,12 @@ module ActivityNotification
17
17
  headers = headers_for(notification.key, options)
18
18
  begin
19
19
  mail headers
20
- rescue ActionView::MissingTemplate
21
- mail headers.merge(template_name: 'default')
20
+ rescue ActionView::MissingTemplate => e
21
+ if options[:fallback].present?
22
+ mail headers.merge(template_name: options[:fallback])
23
+ else
24
+ raise e
25
+ end
22
26
  end
23
27
  end
24
28
 
@@ -117,7 +121,7 @@ module ActivityNotification
117
121
  # mail_subject: '...'
118
122
  #
119
123
  # If one does not exist, it fallbacks to default:
120
- # Notification for #{notification.printable_type}
124
+ # Notification for #{notification.printable_notifiable_type}
121
125
  #
122
126
  # @param [String] key Key of the notification
123
127
  # @return [String] Subject of notification email
@@ -127,7 +131,7 @@ module ActivityNotification
127
131
  k.insert(1, @target.to_resource_name)
128
132
  k = k.join('.')
129
133
  I18n.t(:mail_subject, scope: k,
130
- default: ["Notification of #{@notifiable.printable_type}"])
134
+ default: ["Notification of #{@notifiable.printable_type.downcase}"])
131
135
  end
132
136
 
133
137
  end