activity_notification 0.0.9 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.travis.yml +5 -0
  4. data/.yardopts +3 -0
  5. data/Gemfile +5 -0
  6. data/Gemfile.lock +50 -44
  7. data/README.md +242 -81
  8. data/Rakefile +13 -13
  9. data/activity_notification.gemspec +6 -8
  10. data/app/controllers/activity_notification/notifications_controller.rb +89 -11
  11. data/app/controllers/activity_notification/notifications_with_devise_controller.rb +12 -3
  12. data/app/mailers/activity_notification/mailer.rb +3 -0
  13. data/gemfiles/Gemfile.rails-4.2 +13 -0
  14. data/gemfiles/Gemfile.rails-4.2.lock +190 -0
  15. data/gemfiles/Gemfile.rails-5.0 +14 -0
  16. data/gemfiles/Gemfile.rails-5.0.lock +201 -0
  17. data/lib/activity_notification.rb +10 -6
  18. data/lib/activity_notification/apis/notification_api.rb +137 -27
  19. data/lib/activity_notification/common.rb +48 -24
  20. data/lib/activity_notification/config.rb +68 -10
  21. data/lib/activity_notification/controllers/store_controller.rb +13 -5
  22. data/lib/activity_notification/helpers/polymorphic_helpers.rb +17 -3
  23. data/lib/activity_notification/helpers/view_helpers.rb +161 -45
  24. data/lib/activity_notification/mailers/helpers.rb +121 -83
  25. data/lib/activity_notification/models/concerns/notifiable.rb +162 -69
  26. data/lib/activity_notification/models/concerns/notifier.rb +2 -0
  27. data/lib/activity_notification/models/concerns/target.rb +124 -25
  28. data/lib/activity_notification/models/notification.rb +168 -4
  29. data/lib/activity_notification/rails/routes.rb +50 -48
  30. data/lib/activity_notification/renderable.rb +106 -26
  31. data/lib/activity_notification/roles/acts_as_notifiable.rb +99 -26
  32. data/lib/activity_notification/roles/acts_as_notifier.rb +3 -0
  33. data/lib/activity_notification/roles/acts_as_target.rb +70 -0
  34. data/lib/activity_notification/version.rb +1 -1
  35. data/lib/generators/activity_notification/active_record/migration_generator.rb +3 -1
  36. data/lib/generators/activity_notification/controllers_generator.rb +5 -0
  37. data/lib/generators/activity_notification/install_generator.rb +7 -3
  38. data/lib/generators/activity_notification/models/notification_generator.rb +4 -2
  39. data/lib/generators/activity_notification/views_generator.rb +20 -0
  40. data/spec/concerns/apis/notification_api_spec.rb +105 -36
  41. data/spec/concerns/common_spec.rb +1 -1
  42. data/spec/concerns/models/notifiable_spec.rb +2 -2
  43. data/spec/concerns/models/notifier_spec.rb +1 -1
  44. data/spec/concerns/models/target_spec.rb +9 -8
  45. data/spec/controllers/notifications_controller_shared_examples.rb +101 -28
  46. data/spec/controllers/notifications_with_devise_controller_spec.rb +14 -4
  47. data/spec/helpers/view_helpers_spec.rb +3 -3
  48. data/spec/mailers/mailer_spec.rb +1 -1
  49. data/spec/models/notification_spec.rb +57 -3
  50. data/spec/rails_app/app/models/article.rb +1 -2
  51. data/spec/rails_app/app/models/comment.rb +8 -6
  52. data/spec/rails_app/app/models/user.rb +1 -1
  53. data/spec/rails_app/app/views/layouts/_header.html.erb +2 -0
  54. data/spec/rails_app/config/application.rb +3 -1
  55. data/spec/rails_app/config/environment.rb +12 -2
  56. data/spec/rails_app/config/environments/test.rb +11 -2
  57. data/spec/roles/acts_as_notifiable_spec.rb +2 -2
  58. data/spec/roles/acts_as_notifier_spec.rb +1 -1
  59. data/spec/roles/acts_as_target_spec.rb +3 -3
  60. data/spec/spec_helper.rb +6 -0
  61. metadata +35 -40
  62. data/spec/rails_app/app/models/concerns/.keep +0 -0
@@ -0,0 +1,14 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec path: '../'
4
+
5
+ gem 'rails', '~> 5.0.0'
6
+ gem 'sqlite3'
7
+ gem 'jquery-rails'
8
+
9
+ group :test do
10
+ gem 'ammeter'
11
+ gem 'rails-controller-testing'
12
+ gem 'timecop'
13
+ gem 'coveralls', require: false
14
+ end
@@ -0,0 +1,201 @@
1
+ PATH
2
+ remote: ../
3
+ specs:
4
+ activity_notification (0.0.9)
5
+ activerecord (>= 4.2.0)
6
+ i18n (>= 0.5.0)
7
+ railties (>= 4.2.0, < 5.1)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ actioncable (5.0.0.1)
13
+ actionpack (= 5.0.0.1)
14
+ nio4r (~> 1.2)
15
+ websocket-driver (~> 0.6.1)
16
+ actionmailer (5.0.0.1)
17
+ actionpack (= 5.0.0.1)
18
+ actionview (= 5.0.0.1)
19
+ activejob (= 5.0.0.1)
20
+ mail (~> 2.5, >= 2.5.4)
21
+ rails-dom-testing (~> 2.0)
22
+ actionpack (5.0.0.1)
23
+ actionview (= 5.0.0.1)
24
+ activesupport (= 5.0.0.1)
25
+ rack (~> 2.0)
26
+ rack-test (~> 0.6.3)
27
+ rails-dom-testing (~> 2.0)
28
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
29
+ actionview (5.0.0.1)
30
+ activesupport (= 5.0.0.1)
31
+ builder (~> 3.1)
32
+ erubis (~> 2.7.0)
33
+ rails-dom-testing (~> 2.0)
34
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
35
+ activejob (5.0.0.1)
36
+ activesupport (= 5.0.0.1)
37
+ globalid (>= 0.3.6)
38
+ activemodel (5.0.0.1)
39
+ activesupport (= 5.0.0.1)
40
+ activerecord (5.0.0.1)
41
+ activemodel (= 5.0.0.1)
42
+ activesupport (= 5.0.0.1)
43
+ arel (~> 7.0)
44
+ activesupport (5.0.0.1)
45
+ concurrent-ruby (~> 1.0, >= 1.0.2)
46
+ i18n (~> 0.7)
47
+ minitest (~> 5.1)
48
+ tzinfo (~> 1.1)
49
+ ammeter (1.1.3)
50
+ activesupport (>= 3.0)
51
+ railties (>= 3.0)
52
+ rspec-rails (>= 2.2)
53
+ arel (7.1.1)
54
+ bcrypt (3.1.11)
55
+ builder (3.2.2)
56
+ concurrent-ruby (1.0.2)
57
+ coveralls (0.8.15)
58
+ json (>= 1.8, < 3)
59
+ simplecov (~> 0.12.0)
60
+ term-ansicolor (~> 1.3)
61
+ thor (~> 0.19.1)
62
+ tins (>= 1.6.0, < 2)
63
+ devise (4.2.0)
64
+ bcrypt (~> 3.0)
65
+ orm_adapter (~> 0.1)
66
+ railties (>= 4.1.0, < 5.1)
67
+ responders
68
+ warden (~> 1.2.3)
69
+ diff-lcs (1.2.5)
70
+ docile (1.1.5)
71
+ erubis (2.7.0)
72
+ factory_girl (4.7.0)
73
+ activesupport (>= 3.0.0)
74
+ factory_girl_rails (4.7.0)
75
+ factory_girl (~> 4.7.0)
76
+ railties (>= 3.0.0)
77
+ globalid (0.3.7)
78
+ activesupport (>= 4.1.0)
79
+ i18n (0.7.0)
80
+ jquery-rails (4.2.1)
81
+ rails-dom-testing (>= 1, < 3)
82
+ railties (>= 4.2.0)
83
+ thor (>= 0.14, < 2.0)
84
+ json (2.0.2)
85
+ loofah (2.0.3)
86
+ nokogiri (>= 1.5.9)
87
+ mail (2.6.4)
88
+ mime-types (>= 1.16, < 4)
89
+ method_source (0.8.2)
90
+ mime-types (3.1)
91
+ mime-types-data (~> 3.2015)
92
+ mime-types-data (3.2016.0521)
93
+ mini_portile2 (2.1.0)
94
+ minitest (5.9.0)
95
+ nio4r (1.2.1)
96
+ nokogiri (1.6.8)
97
+ mini_portile2 (~> 2.1.0)
98
+ pkg-config (~> 1.1.7)
99
+ orm_adapter (0.5.0)
100
+ pkg-config (1.1.7)
101
+ rack (2.0.1)
102
+ rack-test (0.6.3)
103
+ rack (>= 1.0)
104
+ rails (5.0.0.1)
105
+ actioncable (= 5.0.0.1)
106
+ actionmailer (= 5.0.0.1)
107
+ actionpack (= 5.0.0.1)
108
+ actionview (= 5.0.0.1)
109
+ activejob (= 5.0.0.1)
110
+ activemodel (= 5.0.0.1)
111
+ activerecord (= 5.0.0.1)
112
+ activesupport (= 5.0.0.1)
113
+ bundler (>= 1.3.0, < 2.0)
114
+ railties (= 5.0.0.1)
115
+ sprockets-rails (>= 2.0.0)
116
+ rails-controller-testing (1.0.1)
117
+ actionpack (~> 5.x)
118
+ actionview (~> 5.x)
119
+ activesupport (~> 5.x)
120
+ rails-dom-testing (2.0.1)
121
+ activesupport (>= 4.2.0, < 6.0)
122
+ nokogiri (~> 1.6.0)
123
+ rails-html-sanitizer (1.0.3)
124
+ loofah (~> 2.0)
125
+ railties (5.0.0.1)
126
+ actionpack (= 5.0.0.1)
127
+ activesupport (= 5.0.0.1)
128
+ method_source
129
+ rake (>= 0.8.7)
130
+ thor (>= 0.18.1, < 2.0)
131
+ rake (11.2.2)
132
+ responders (2.3.0)
133
+ railties (>= 4.2.0, < 5.1)
134
+ rspec-core (3.5.2)
135
+ rspec-support (~> 3.5.0)
136
+ rspec-expectations (3.5.0)
137
+ diff-lcs (>= 1.2.0, < 2.0)
138
+ rspec-support (~> 3.5.0)
139
+ rspec-mocks (3.5.0)
140
+ diff-lcs (>= 1.2.0, < 2.0)
141
+ rspec-support (~> 3.5.0)
142
+ rspec-rails (3.5.2)
143
+ actionpack (>= 3.0)
144
+ activesupport (>= 3.0)
145
+ railties (>= 3.0)
146
+ rspec-core (~> 3.5.0)
147
+ rspec-expectations (~> 3.5.0)
148
+ rspec-mocks (~> 3.5.0)
149
+ rspec-support (~> 3.5.0)
150
+ rspec-support (3.5.0)
151
+ simplecov (0.12.0)
152
+ docile (~> 1.1.0)
153
+ json (>= 1.8, < 3)
154
+ simplecov-html (~> 0.10.0)
155
+ simplecov-html (0.10.0)
156
+ sprockets (3.7.0)
157
+ concurrent-ruby (~> 1.0)
158
+ rack (> 1, < 3)
159
+ sprockets-rails (3.1.1)
160
+ actionpack (>= 4.0)
161
+ activesupport (>= 4.0)
162
+ sprockets (>= 3.0.0)
163
+ sqlite3 (1.3.11)
164
+ term-ansicolor (1.3.2)
165
+ tins (~> 1.0)
166
+ thor (0.19.1)
167
+ thread_safe (0.3.5)
168
+ timecop (0.8.1)
169
+ tins (1.12.0)
170
+ tzinfo (1.2.2)
171
+ thread_safe (~> 0.1)
172
+ warden (1.2.6)
173
+ rack (>= 1.0)
174
+ websocket-driver (0.6.4)
175
+ websocket-extensions (>= 0.1.0)
176
+ websocket-extensions (0.1.2)
177
+ yard (0.9.5)
178
+ yard-activesupport-concern (0.0.1)
179
+ yard (>= 0.8)
180
+
181
+ PLATFORMS
182
+ ruby
183
+
184
+ DEPENDENCIES
185
+ activity_notification!
186
+ ammeter
187
+ coveralls
188
+ devise (~> 4.2.0)
189
+ factory_girl_rails (~> 4.7.0)
190
+ jquery-rails
191
+ rails (~> 5.0.0)
192
+ rails-controller-testing
193
+ rspec-rails (~> 3.5.1)
194
+ simplecov (~> 0.12.0)
195
+ sqlite3
196
+ timecop
197
+ yard (~> 0.9.5)
198
+ yard-activesupport-concern (~> 0.0.1)
199
+
200
+ BUNDLED WITH
201
+ 1.12.5
@@ -22,19 +22,23 @@ module ActivityNotification
22
22
  autoload :Helpers, 'activity_notification/mailers/helpers'
23
23
  end
24
24
 
25
- # Returns ActivityNotification's configuration object.
25
+ # Returns configuration object of ActivityNotification.
26
26
  def self.config
27
27
  @config ||= ActivityNotification::Config.new
28
28
  end
29
29
 
30
- # Lets you set global configuration options.
31
- #
30
+ # Sets global configuration options for ActivityNotification.
32
31
  # All available options and their defaults are in the example below:
33
32
  # @example Initializer for Rails
34
33
  # ActivityNotification.configure do |config|
35
- # config.enabled = false
36
- # config.table_name = "notifications"
37
- # ...
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
38
42
  # end
39
43
  def self.configure(&block)
40
44
  yield(config) if block_given?
@@ -1,25 +1,77 @@
1
1
  module ActivityNotification
2
+ # Defines API for notification included in Notification model.
2
3
  module NotificationApi
3
4
  extend ActiveSupport::Concern
4
5
 
5
- # Define store_notification as private clas method
6
6
  included do
7
+ # Defines store_notification as private clas method
7
8
  private_class_method :store_notification
8
9
  end
9
10
 
10
- # For notification API
11
11
  class_methods do
12
+ # Generates notifications to configured targets with notifiable model.
13
+ #
14
+ # @example Use with target_type as Symbol
15
+ # ActivityNotification::Notification.notify :users, @comment
16
+ # @example Use with target_type as String
17
+ # ActivityNotification::Notification.notify 'User', @comment
18
+ # @example Use with target_type as Class
19
+ # ActivityNotification::Notification.notify User, @comment
20
+ # @example Use with options
21
+ # ActivityNotification::Notification.notify :users, @comment, key: 'custom.comment', group: @comment.article
22
+ # ActivityNotification::Notification.notify :users, @comment, parameters: { reply_to: @comment.reply_to }, send_later: false
23
+ #
24
+ # @param [Symbol, String, Class] target_type Type of target
25
+ # @param [Object] notifiable Notifiable instance
26
+ # @param [Hash] options Options for notifications
27
+ # @option options [String] :key (notifiable.default_notification_key) Key of the notification
28
+ # @option options [Object] :group (nil) Group unit of the notifications
29
+ # @option options [Object] :notifier (nil) Notifier of the notifications
30
+ # @option options [Hash] :parameters ({}) Additional parameters of the notifications
31
+ # @option options [Boolean] :send_email (true) If it sends notification email
32
+ # @option options [Boolean] :send_later (true) If it sends notification email asynchronously
33
+ # @return [Array<Notificaion>] Array of generated notifications
12
34
  def notify(target_type, notifiable, options = {})
13
35
  targets = notifiable.notification_targets(target_type, options[:key])
14
36
  unless targets.blank?
15
37
  notify_all(targets, notifiable, options)
16
38
  end
17
39
  end
18
-
40
+
41
+ # Generates notifications to specified targets.
42
+ #
43
+ # @example Notify to all users
44
+ # ActivityNotification::Notification.notify_all User.all, @comment
45
+ #
46
+ # @param [Array<Object>] targets Targets to send notifications
47
+ # @param [Object] notifiable Notifiable instance
48
+ # @param [Hash] options Options for notifications
49
+ # @option options [String] :key (notifiable.default_notification_key) Key of the notification
50
+ # @option options [Object] :group (nil) Group unit of the notifications
51
+ # @option options [Object] :notifier (nil) Notifier of the notifications
52
+ # @option options [Hash] :parameters ({}) Additional parameters of the notifications
53
+ # @option options [Boolean] :send_email (true) Whether it sends notification email
54
+ # @option options [Boolean] :send_later (true) Whether it sends notification email asynchronously
55
+ # @return [Array<Notificaion>] Array of generated notifications
19
56
  def notify_all(targets, notifiable, options = {})
20
57
  Array(targets).map { |target| notify_to(target, notifiable, options) }
21
58
  end
22
-
59
+
60
+ # Generates notifications to one target.
61
+ #
62
+ # @example Notify to one user
63
+ # ActivityNotification::Notification.notify_to @comment.auther, @comment
64
+ #
65
+ # @param [Object] target Target to send notifications
66
+ # @param [Object] notifiable Notifiable instance
67
+ # @param [Hash] options Options for notifications
68
+ # @option options [String] :key (notifiable.default_notification_key) Key of the notification
69
+ # @option options [Object] :group (nil) Group unit of the notifications
70
+ # @option options [Object] :notifier (nil) Notifier of the notifications
71
+ # @option options [Hash] :parameters ({}) Additional parameters of the notifications
72
+ # @option options [Boolean] :send_email (true) Whether it sends notification email
73
+ # @option options [Boolean] :send_later (true) Whether it sends notification email asynchronously
74
+ # @return [Notification] Generated notification instance
23
75
  def notify_to(target, notifiable, options = {})
24
76
  send_email = options.has_key?(:send_email) ? options[:send_email] : true
25
77
  send_later = options.has_key?(:send_later) ? options[:send_later] : true
@@ -30,25 +82,42 @@ module ActivityNotification
30
82
  # Return created notification
31
83
  notification
32
84
  end
33
-
34
- # Open all notifications of specified target
35
- def open_all_of(target, opened_at = nil)
36
- opened_at = DateTime.now if opened_at.blank?
37
- where(target: target, opened_at: nil).update_all(opened_at: opened_at)
85
+
86
+ # Opens all notifications of the target.
87
+ #
88
+ # @param [Object] target Target of the notifications to open
89
+ # @param [Hash] options Options for opening notifications
90
+ # @option options [DateTime] :opened_at (DateTime.now) Time to set to opened_at of the notification record
91
+ # @option options [String] :filtered_by_type (nil) Notifiable type for filter
92
+ # @option options [Object] :filtered_by_group (nil) Group instance for filter
93
+ # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
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
96
+ # @return [Integer] Number of opened notification records
97
+ # @todo Add filter option
98
+ def open_all_of(target, options = {})
99
+ opened_at = options[:opened_at] || DateTime.now
100
+ target.notifications.unopened_only.filtered_by_options(options).update_all(opened_at: opened_at)
38
101
  end
39
102
 
40
- #TODO description
41
- # Call from controllers or views to avoid N+1
103
+ # Returns if group member of the notifications exists.
104
+ # This method is designed to be called from controllers or views to avoid N+1.
105
+ #
106
+ # @param [Array<Notificaion> | ActiveRecord_AssociationRelation<Notificaion>] notifications Array or database query of the notifications to test member exists
107
+ # @return [Boolean] If group member of the notifications exists
42
108
  def group_member_exists?(notifications)
43
- notifications.present? && where(group_owner_id: notifications.pluck(:id)).exists?
109
+ notifications.present? && where(group_owner_id: notifications.map(&:id)).exists?
44
110
  end
45
-
111
+
112
+ # Returns available options for kinds of notify methods.
113
+ #
114
+ # @return [Array<Notificaion>] Available options for kinds of notify methods
46
115
  def available_options
47
116
  [:key, :group, :parameters, :notifier, :send_email, :send_later].freeze
48
117
  end
49
118
 
50
- # Private class methods
51
-
119
+ # Stores notifications to datastore
120
+ # @api private
52
121
  def store_notification(target, notifiable, options = {})
53
122
  target_type = target.to_class_name
54
123
  key = options[:key] || notifiable.default_notification_key
@@ -57,7 +126,7 @@ module ActivityNotification
57
126
  parameters = options[:parameters] || {}
58
127
  parameters.merge!(options.except(*available_options))
59
128
  parameters.merge!(notifiable.notification_parameters(target_type, key))
60
-
129
+
61
130
  # Bundle notification group by target, notifiable_type, group and key
62
131
  # Defferent notifiable.id can be made in a same group
63
132
  group_owner = where(target: target, notifiable_type: notifiable.to_class_name, key: key, group: group)
@@ -71,8 +140,10 @@ module ActivityNotification
71
140
  end
72
141
 
73
142
 
74
- # Public instance methods
75
-
143
+ # Sends notification email to the target.
144
+ #
145
+ # @param [Boolean] send_later If it sends notification email asynchronously
146
+ # @return [Mail::Message, ActionMailer::DeliveryJob] Email message or its delivery job
76
147
  def send_notification_email(send_later = true)
77
148
  if send_later
78
149
  Mailer.send_notification_email(self).deliver_later
@@ -81,34 +152,61 @@ module ActivityNotification
81
152
  end
82
153
  end
83
154
 
84
- def open!(opened_at = nil)
85
- opened_at = DateTime.now if opened_at.blank?
155
+ # Opens the notification.
156
+ #
157
+ # @param [Hash] options Options for opening notifications
158
+ # @option options [DateTime] :opened_at (DateTime.now) Time to set to opened_at of the notification record
159
+ # @option options [Boolean] :with_members (true) If it opens notifications including group members
160
+ # @return [Integer] Number of opened notification records
161
+ def open!(options = {})
162
+ opened_at = options[:opened_at] || DateTime.now
163
+ with_members = options.has_key?(:with_members) ? options[:with_members] : true
86
164
  update(opened_at: opened_at)
87
- group_members.update_all(opened_at: opened_at) + 1
165
+ with_members ? group_members.update_all(opened_at: opened_at) + 1 : 1
88
166
  end
89
167
 
168
+ # Returns if the notification is unopened.
169
+ #
170
+ # @return [Boolean] If the notification is unopened
90
171
  def unopened?
91
172
  !opened?
92
173
  end
93
174
 
175
+ # Returns if the notification is opened.
176
+ #
177
+ # @return [Boolean] If the notification is opened
94
178
  def opened?
95
179
  opened_at.present?
96
180
  end
97
181
 
182
+ # Returns if the notification is group owner.
183
+ #
184
+ # @return [Boolean] If the notification is group owner
98
185
  def group_owner?
99
186
  group_owner_id.blank?
100
187
  end
101
188
 
189
+ # Returns if the notification is group member belonging to owner.
190
+ #
191
+ # @return [Boolean] If the notification is group member
102
192
  def group_member?
103
193
  group_owner_id.present?
104
194
  end
105
195
 
106
- # Cache group-by query result to avoid N+1 call
196
+ # Returns if group member of the notification exists.
197
+ # This method is designed to cache group by query result to avoid N+1 call.
198
+ #
199
+ # @param [Integer] limit Limit to query for opened notifications
200
+ # @return [Boolean] If group member of the notification exists
107
201
  def group_member_exists?(limit = ActivityNotification.config.opened_limit)
108
202
  group_member_count(limit) > 0
109
203
  end
110
204
 
111
- # Cache group-by query result to avoid N+1 call
205
+ # Returns count of group members of the notification.
206
+ # This method is designed to cache group by query result to avoid N+1 call.
207
+ #
208
+ # @param [Integer] limit Limit to query for opened notifications
209
+ # @return [Integer] Count of group members of the notification
112
210
  def group_member_count(limit = ActivityNotification.config.opened_limit)
113
211
  notification = group_member? ? group_owner : self
114
212
  notification.opened? ?
@@ -116,16 +214,23 @@ module ActivityNotification
116
214
  notification.unopened_group_member_count
117
215
  end
118
216
 
217
+ # Returns notifiable_path to move after opening notification with notifiable.notifiable_path.
218
+ #
219
+ # @return [String] Notifiable path URL to move after opening notification
119
220
  def notifiable_path
120
- notifiable.notifiable_path(target_type)
221
+ notifiable.notifiable_path(target_type, key)
121
222
  end
122
223
 
123
224
 
124
- # Protected instance methods
125
225
  protected
126
226
 
227
+ # Returns count of group members of the unopened notification.
228
+ # This method is designed to cache group by query result to avoid N+1 call.
229
+ # @api protected
230
+ #
231
+ # @return [Integer] Count of group members of the unopened notification
127
232
  def unopened_group_member_count
128
- # Cache group-by query result to avoid N+1 call
233
+ # Cache group by query result to avoid N+1 call
129
234
  unopened_group_member_counts = target.notifications
130
235
  .unopened_index_group_members_only
131
236
  .group(:group_owner_id)
@@ -133,8 +238,13 @@ module ActivityNotification
133
238
  unopened_group_member_counts[id] || 0
134
239
  end
135
240
 
241
+ # Returns count of group members of the opened notification.
242
+ # This method is designed to cache group by query result to avoid N+1 call.
243
+ # @api protected
244
+ #
245
+ # @return [Integer] Count of group members of the opened notification
136
246
  def opened_group_member_count(limit = ActivityNotification.config.opened_limit)
137
- # Cache group-by query result to avoid N+1 call
247
+ # Cache group by query result to avoid N+1 call
138
248
  opened_group_member_counts = target.notifications
139
249
  .opened_index_group_members_only(limit)
140
250
  .group(:group_owner_id)