activity_notification 2.5.1 → 2.6.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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -0
  3. data/app/channels/activity_notification/notification_api_channel.rb +5 -5
  4. data/app/channels/activity_notification/notification_api_with_devise_channel.rb +4 -4
  5. data/app/channels/activity_notification/notification_channel.rb +4 -0
  6. data/app/channels/activity_notification/notification_with_devise_channel.rb +4 -4
  7. data/app/controllers/activity_notification/notifications_controller.rb +1 -2
  8. data/app/controllers/activity_notification/subscriptions_controller.rb +2 -3
  9. data/app/jobs/activity_notification/notify_all_job.rb +2 -2
  10. data/app/jobs/activity_notification/notify_job.rb +2 -2
  11. data/app/jobs/activity_notification/notify_to_job.rb +1 -1
  12. data/app/mailers/activity_notification/mailer.rb +1 -1
  13. data/app/views/activity_notification/mailer/default/batch_default.text.erb +1 -1
  14. data/app/views/activity_notification/notifications/default/index.html.erb +1 -1
  15. data/app/views/activity_notification/subscriptions/default/_notification_keys.html.erb +1 -1
  16. data/app/views/activity_notification/subscriptions/default/_subscription.html.erb +1 -1
  17. data/docs/Functions.md +93 -9
  18. data/docs/Setup.md +7 -7
  19. data/docs/Testing.md +1 -1
  20. data/docs/Upgrade-to-2.6.md +108 -0
  21. data/lib/activity_notification/apis/notification_api.rb +55 -40
  22. data/lib/activity_notification/apis/subscription_api.rb +10 -10
  23. data/lib/activity_notification/common.rb +5 -5
  24. data/lib/activity_notification/config.rb +15 -5
  25. data/lib/activity_notification/controllers/common_controller.rb +2 -4
  26. data/lib/activity_notification/controllers/devise_authentication_controller.rb +2 -2
  27. data/lib/activity_notification/helpers/polymorphic_helpers.rb +6 -6
  28. data/lib/activity_notification/helpers/view_helpers.rb +3 -3
  29. data/lib/activity_notification/mailers/helpers.rb +88 -2
  30. data/lib/activity_notification/models/concerns/notifiable.rb +60 -30
  31. data/lib/activity_notification/models/concerns/notifier.rb +1 -1
  32. data/lib/activity_notification/models/concerns/subscriber.rb +72 -15
  33. data/lib/activity_notification/models/concerns/target.rb +38 -35
  34. data/lib/activity_notification/optional_targets/action_cable_api_channel.rb +1 -1
  35. data/lib/activity_notification/optional_targets/slack.rb +2 -2
  36. data/lib/activity_notification/orm/active_record/notification.rb +25 -25
  37. data/lib/activity_notification/orm/active_record/subscription.rb +21 -1
  38. data/lib/activity_notification/orm/dynamoid/extension.rb +3 -3
  39. data/lib/activity_notification/orm/dynamoid/subscription.rb +8 -1
  40. data/lib/activity_notification/orm/dynamoid.rb +18 -18
  41. data/lib/activity_notification/orm/mongoid/notification.rb +26 -28
  42. data/lib/activity_notification/orm/mongoid/subscription.rb +21 -1
  43. data/lib/activity_notification/orm/mongoid.rb +1 -1
  44. data/lib/activity_notification/rails/routes.rb +11 -11
  45. data/lib/activity_notification/roles/acts_as_group.rb +1 -1
  46. data/lib/activity_notification/roles/acts_as_notifiable.rb +5 -5
  47. data/lib/activity_notification/roles/acts_as_notifier.rb +1 -1
  48. data/lib/activity_notification/roles/acts_as_target.rb +1 -1
  49. data/lib/activity_notification/version.rb +1 -1
  50. data/lib/generators/activity_notification/add_notifiable_to_subscriptions/add_notifiable_to_subscriptions_generator.rb +23 -0
  51. data/lib/generators/activity_notification/add_notifiable_to_subscriptions/templates/add_notifiable_to_subscriptions.rb +13 -0
  52. data/lib/generators/templates/activity_notification.rb +14 -2
  53. data/lib/generators/templates/migrations/migration.rb +4 -2
  54. metadata +5 -2
@@ -117,7 +117,7 @@ class ActiveModel::NullMutationTracker
117
117
  def force_change(attr_name); end if Rails::VERSION::MAJOR >= 6
118
118
  end
119
119
 
120
- # Entend Dynamoid to support ActivityNotification scope in Dynamoid::Criteria::Chain
120
+ # Extend Dynamoid to support ActivityNotification scope in Dynamoid::Criteria::Chain
121
121
  # @private
122
122
  module Dynamoid # :nodoc: all
123
123
  # https://github.com/Dynamoid/dynamoid/blob/master/lib/dynamoid/criteria.rb
@@ -147,7 +147,7 @@ module Dynamoid # :nodoc: all
147
147
  # is defined same as
148
148
  # ActivityNotification::Notification.unopened_only.group_owners_only.latest_order
149
149
  # @scope class
150
- # @example Get unopened notificaton index of the @user
150
+ # @example Get unopened notification index of the @user
151
151
  # @notifications = @user.notifications.unopened_index
152
152
  # @notifications = @user.notifications.unopened_only.group_owners_only.latest_order
153
153
  # @param [Boolean] reverse If notification index will be ordered as earliest first
@@ -163,7 +163,7 @@ module Dynamoid # :nodoc: all
163
163
  # is defined same as
164
164
  # ActivityNotification::Notification.opened_only(limit).group_owners_only.latest_order
165
165
  # @scope class
166
- # @example Get unopened notificaton index of the @user with limit 10
166
+ # @example Get unopened notification index of the @user with limit 10
167
167
  # @notifications = @user.notifications.opened_index(10)
168
168
  # @notifications = @user.notifications.opened_only(10).group_owners_only.latest_order
169
169
  # @param [Integer] limit Limit to query for opened notifications
@@ -217,7 +217,7 @@ module Dynamoid # :nodoc: all
217
217
  end
218
218
 
219
219
  # Selects filtered notifications by notifiable instance.
220
- # @example Get filtered unopened notificatons of the @user for @comment as notifiable
220
+ # @example Get filtered unopened notifications of the @user for @comment as notifiable
221
221
  # @notifications = @user.notifications.unopened_only.filtered_by_instance(@comment)
222
222
  # @scope class
223
223
  # @param [Object] notifiable Notifiable instance for filter
@@ -227,7 +227,7 @@ module Dynamoid # :nodoc: all
227
227
  end
228
228
 
229
229
  # Selects filtered notifications by group instance.
230
- # @example Get filtered unopened notificatons of the @user for @article as group
230
+ # @example Get filtered unopened notifications of the @user for @article as group
231
231
  # @notifications = @user.notifications.unopened_only.filtered_by_group(@article)
232
232
  # @scope class
233
233
  # @param [Object] group Group instance for filter
@@ -237,7 +237,7 @@ module Dynamoid # :nodoc: all
237
237
  end
238
238
 
239
239
  # Selects filtered notifications or subscriptions by target_type.
240
- # @example Get filtered unopened notificatons of User as target type
240
+ # @example Get filtered unopened notifications of User as target type
241
241
  # @notifications = ActivityNotification.Notification.unopened_only.filtered_by_target_type('User')
242
242
  # @scope class
243
243
  # @param [String] target_type Target type for filter
@@ -247,7 +247,7 @@ module Dynamoid # :nodoc: all
247
247
  end
248
248
 
249
249
  # Selects filtered notifications by notifiable_type.
250
- # @example Get filtered unopened notificatons of the @user for Comment notifiable class
250
+ # @example Get filtered unopened notifications of the @user for Comment notifiable class
251
251
  # @notifications = @user.notifications.unopened_only.filtered_by_type('Comment')
252
252
  # @scope class
253
253
  # @param [String] notifiable_type Notifiable type for filter
@@ -257,7 +257,7 @@ module Dynamoid # :nodoc: all
257
257
  end
258
258
 
259
259
  # Selects filtered notifications or subscriptions by key.
260
- # @example Get filtered unopened notificatons of the @user with key 'comment.reply'
260
+ # @example Get filtered unopened notifications of the @user with key 'comment.reply'
261
261
  # @notifications = @user.notifications.unopened_only.filtered_by_key('comment.reply')
262
262
  # @scope class
263
263
  # @param [String] key Key of the notification for filter
@@ -267,37 +267,37 @@ module Dynamoid # :nodoc: all
267
267
  end
268
268
 
269
269
  # Selects filtered notifications later than specified time.
270
- # @example Get filtered unopened notificatons of the @user later than @notification
270
+ # @example Get filtered unopened notifications of the @user later than @notification
271
271
  # @notifications = @user.notifications.unopened_only.later_than(@notification.created_at)
272
272
  # @scope class
273
273
  # @param [Time] Created time of the notifications for filter
274
- # @return [ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>] Database query of filtered notifications
274
+ # @return [ActiveRecord_AssociationRelation<Notification>, Mongoid::Criteria<Notification>] Database query of filtered notifications
275
275
  def later_than(created_time)
276
276
  where('created_at.gt': created_time)
277
277
  end
278
278
 
279
279
  # Selects filtered notifications earlier than specified time.
280
- # @example Get filtered unopened notificatons of the @user earlier than @notification
280
+ # @example Get filtered unopened notifications of the @user earlier than @notification
281
281
  # @notifications = @user.notifications.unopened_only.earlier_than(@notification.created_at)
282
282
  # @scope class
283
283
  # @param [Time] Created time of the notifications for filter
284
- # @return [ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>] Database query of filtered notifications
284
+ # @return [ActiveRecord_AssociationRelation<Notification>, Mongoid::Criteria<Notification>] Database query of filtered notifications
285
285
  def earlier_than(created_time)
286
286
  where('created_at.lt': created_time)
287
287
  end
288
288
 
289
289
  # Selects filtered notifications or subscriptions by notifiable_type, group or key with filter options.
290
- # @example Get filtered unopened notificatons of the @user for Comment notifiable class
290
+ # @example Get filtered unopened notifications of the @user for Comment notifiable class
291
291
  # @notifications = @user.notifications.unopened_only.filtered_by_options({ filtered_by_type: 'Comment' })
292
- # @example Get filtered unopened notificatons of the @user for @article as group
292
+ # @example Get filtered unopened notifications of the @user for @article as group
293
293
  # @notifications = @user.notifications.unopened_only.filtered_by_options({ filtered_by_group: @article })
294
- # @example Get filtered unopened notificatons of the @user for Article instance id=1 as group
294
+ # @example Get filtered unopened notifications of the @user for Article instance id=1 as group
295
295
  # @notifications = @user.notifications.unopened_only.filtered_by_options({ filtered_by_group_type: 'Article', filtered_by_group_id: '1' })
296
- # @example Get filtered unopened notificatons of the @user with key 'comment.reply'
296
+ # @example Get filtered unopened notifications of the @user with key 'comment.reply'
297
297
  # @notifications = @user.notifications.unopened_only.filtered_by_options({ filtered_by_key: 'comment.reply' })
298
- # @example Get filtered unopened notificatons of the @user for Comment notifiable class with key 'comment.reply'
298
+ # @example Get filtered unopened notifications of the @user for Comment notifiable class with key 'comment.reply'
299
299
  # @notifications = @user.notifications.unopened_only.filtered_by_options({ filtered_by_type: 'Comment', filtered_by_key: 'comment.reply' })
300
- # @example Get custom filtered notificatons of the @user
300
+ # @example Get custom filtered notifications of the @user
301
301
  # @notifications = @user.notifications.unopened_only.filtered_by_options({ custom_filter: ["created_at >= ?", time.hour.ago] })
302
302
  # @scope class
303
303
  # @param [Hash] options Options for filter
@@ -47,7 +47,7 @@ module ActivityNotification
47
47
  # Only group owner instance has :group_members value.
48
48
  # Group member instance has nil as :group_members association.
49
49
  # @scope instance
50
- # @return [Mongoid::Criteria<Notificaion>] Database query of the group member notification instances of this notification
50
+ # @return [Mongoid::Criteria<Notification>] Database query of the group member notification instances of this notification
51
51
  has_many :group_members, class_name: "ActivityNotification::Notification", foreign_key: :group_owner_id
52
52
 
53
53
  # Belongs to :otifier instance of this notification.
@@ -66,52 +66,52 @@ module ActivityNotification
66
66
 
67
67
  # Selects group owner notifications only.
68
68
  # @scope class
69
- # @return [Mongoid::Criteria<Notificaion>] Database query of filtered notifications
69
+ # @return [Mongoid::Criteria<Notification>] Database query of filtered notifications
70
70
  scope :group_owners_only, -> { where(:group_owner_id.exists => false) }
71
71
 
72
72
  # Selects group member notifications only.
73
73
  # @scope class
74
- # @return [Mongoid::Criteria<Notificaion>] Database query of filtered notifications
74
+ # @return [Mongoid::Criteria<Notification>] Database query of filtered notifications
75
75
  scope :group_members_only, -> { where(:group_owner_id.exists => true) }
76
76
 
77
77
  # Selects unopened notifications only.
78
78
  # @scope class
79
- # @return [Mongoid::Criteria<Notificaion>] Database query of filtered notifications
79
+ # @return [Mongoid::Criteria<Notification>] Database query of filtered notifications
80
80
  scope :unopened_only, -> { where(:opened_at.exists => false) }
81
81
 
82
82
  # Selects opened notifications only without limit.
83
83
  # Be careful to get too many records with this method.
84
84
  # @scope class
85
- # @return [Mongoid::Criteria<Notificaion>] Database query of filtered notifications
85
+ # @return [Mongoid::Criteria<Notification>] Database query of filtered notifications
86
86
  scope :opened_only!, -> { where(:opened_at.exists => true) }
87
87
 
88
88
  # Selects opened notifications only with limit.
89
89
  # @scope class
90
90
  # @param [Integer] limit Limit to query for opened notifications
91
- # @return [Mongoid::Criteria<Notificaion>] Database query of filtered notifications
91
+ # @return [Mongoid::Criteria<Notification>] Database query of filtered notifications
92
92
  scope :opened_only, ->(limit) { limit == 0 ? none : opened_only!.limit(limit) }
93
93
 
94
94
  # Selects group member notifications in unopened_index.
95
95
  # @scope class
96
- # @return [Mongoid::Criteria<Notificaion>] Database query of filtered notifications
96
+ # @return [Mongoid::Criteria<Notification>] Database query of filtered notifications
97
97
  scope :unopened_index_group_members_only, -> { where(:group_owner_id.in => unopened_index.map(&:id)) }
98
98
 
99
99
  # Selects group member notifications in opened_index.
100
100
  # @scope class
101
101
  # @param [Integer] limit Limit to query for opened notifications
102
- # @return [Mongoid::Criteria<Notificaion>] Database query of filtered notifications
102
+ # @return [Mongoid::Criteria<Notification>] Database query of filtered notifications
103
103
  scope :opened_index_group_members_only, ->(limit) { where(:group_owner_id.in => opened_index(limit).map(&:id)) }
104
104
 
105
105
  # Selects notifications within expiration.
106
106
  # @scope class
107
107
  # @param [ActiveSupport::Duration] expiry_delay Expiry period of notifications
108
- # @return [Mongoid::Criteria<Notificaion>] Database query of filtered notifications
108
+ # @return [Mongoid::Criteria<Notification>] Database query of filtered notifications
109
109
  scope :within_expiration_only, ->(expiry_delay) { where(:created_at.gt => expiry_delay.ago) }
110
110
 
111
111
  # Selects group member notifications with specified group owner ids.
112
112
  # @scope class
113
113
  # @param [Array<String>] owner_ids Array of group owner ids
114
- # @return [Mongoid::Criteria<Notificaion>] Database query of filtered notifications
114
+ # @return [Mongoid::Criteria<Notification>] Database query of filtered notifications
115
115
  scope :group_members_of_owner_ids_only, ->(owner_ids) { where(:group_owner_id.in => owner_ids) }
116
116
 
117
117
  # Selects filtered notifications by target instance.
@@ -120,69 +120,67 @@ module ActivityNotification
120
120
  # @user.notifications
121
121
  # @scope class
122
122
  # @param [Object] target Target instance for filter
123
- # @return [Mongoid::Criteria<Notificaion>] Database query of filtered notifications
123
+ # @return [Mongoid::Criteria<Notification>] Database query of filtered notifications
124
124
  scope :filtered_by_target, ->(target) { filtered_by_association("target", target) }
125
125
 
126
126
  # Selects filtered notifications by notifiable instance.
127
- # @example Get filtered unopened notificatons of the @user for @comment as notifiable
127
+ # @example Get filtered unopened notifications of the @user for @comment as notifiable
128
128
  # @notifications = @user.notifications.unopened_only.filtered_by_instance(@comment)
129
129
  # @scope class
130
130
  # @param [Object] notifiable Notifiable instance for filter
131
- # @return [Mongoid::Criteria<Notificaion>] Database query of filtered notifications
131
+ # @return [Mongoid::Criteria<Notification>] Database query of filtered notifications
132
132
  scope :filtered_by_instance, ->(notifiable) { filtered_by_association("notifiable", notifiable) }
133
133
 
134
134
  # Selects filtered notifications by group instance.
135
- # @example Get filtered unopened notificatons of the @user for @article as group
135
+ # @example Get filtered unopened notifications of the @user for @article as group
136
136
  # @notifications = @user.notifications.unopened_only.filtered_by_group(@article)
137
137
  # @scope class
138
138
  # @param [Object] group Group instance for filter
139
- # @return [Mongoid::Criteria<Notificaion>] Database query of filtered notifications
139
+ # @return [Mongoid::Criteria<Notification>] Database query of filtered notifications
140
140
  scope :filtered_by_group, ->(group) {
141
141
  group.present? ?
142
142
  where(group_id: group.id, group_type: group.class.name) :
143
- Gem::Version.new(::Mongoid::VERSION) >= Gem::Version.new('7.1.0') ?
144
- where(:group_id.exists => false, :group_type.exists => false).or(group_id: nil, group_type: nil) :
145
- any_of({ :group_id.exists => false, :group_type.exists => false }, { group_id: nil, group_type: nil })
143
+ Gem::Version.new(::Mongoid::VERSION) >= Gem::Version.new('7.1.0') ? where(:group_id.exists => false, :group_type.exists => false).or(group_id: nil, group_type: nil) : any_of({ :group_id.exists => false, :group_type.exists => false }, { group_id: nil, group_type: nil })
146
144
  }
147
145
 
148
146
  # Selects filtered notifications later than specified time.
149
- # @example Get filtered unopened notificatons of the @user later than @notification
147
+ # @example Get filtered unopened notifications of the @user later than @notification
150
148
  # @notifications = @user.notifications.unopened_only.later_than(@notification.created_at)
151
149
  # @scope class
152
150
  # @param [Time] Created time of the notifications for filter
153
- # @return [ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>] Database query of filtered notifications
151
+ # @return [ActiveRecord_AssociationRelation<Notification>, Mongoid::Criteria<Notification>] Database query of filtered notifications
154
152
  scope :later_than, ->(created_time) { where(:created_at.gt => created_time) }
155
153
 
156
154
  # Selects filtered notifications earlier than specified time.
157
- # @example Get filtered unopened notificatons of the @user earlier than @notification
155
+ # @example Get filtered unopened notifications of the @user earlier than @notification
158
156
  # @notifications = @user.notifications.unopened_only.earlier_than(@notification.created_at)
159
157
  # @scope class
160
158
  # @param [Time] Created time of the notifications for filter
161
- # @return [ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>] Database query of filtered notifications
159
+ # @return [ActiveRecord_AssociationRelation<Notification>, Mongoid::Criteria<Notification>] Database query of filtered notifications
162
160
  scope :earlier_than, ->(created_time) { where(:created_at.lt => created_time) }
163
161
 
164
162
  # Includes target instance with query for notifications.
165
- # @return [Mongoid::Criteria<Notificaion>] Database query of notifications with target
163
+ # @return [Mongoid::Criteria<Notification>] Database query of notifications with target
166
164
  scope :with_target, -> { }
167
165
 
168
166
  # Includes notifiable instance with query for notifications.
169
- # @return [Mongoid::Criteria<Notificaion>] Database query of notifications with notifiable
167
+ # @return [Mongoid::Criteria<Notification>] Database query of notifications with notifiable
170
168
  scope :with_notifiable, -> { }
171
169
 
172
170
  # Includes group instance with query for notifications.
173
- # @return [Mongoid::Criteria<Notificaion>] Database query of notifications with group
171
+ # @return [Mongoid::Criteria<Notification>] Database query of notifications with group
174
172
  scope :with_group, -> { }
175
173
 
176
174
  # Includes group owner instances with query for notifications.
177
- # @return [Mongoid::Criteria<Notificaion>] Database query of notifications with group owner
175
+ # @return [Mongoid::Criteria<Notification>] Database query of notifications with group owner
178
176
  scope :with_group_owner, -> { }
179
177
 
180
178
  # Includes group member instances with query for notifications.
181
- # @return [Mongoid::Criteria<Notificaion>] Database query of notifications with group members
179
+ # @return [Mongoid::Criteria<Notification>] Database query of notifications with group members
182
180
  scope :with_group_members, -> { }
183
181
 
184
182
  # Includes notifier instance with query for notifications.
185
- # @return [Mongoid::Criteria<Notificaion>] Database query of notifications with notifier
183
+ # @return [Mongoid::Criteria<Notification>] Database query of notifications with notifier
186
184
  scope :with_notifier, -> { }
187
185
 
188
186
  # Dummy reload method for test of notifications.
@@ -18,6 +18,13 @@ module ActivityNotification
18
18
  # @return [Object] Target instance of this subscription
19
19
  belongs_to_polymorphic_xdb_record :target
20
20
 
21
+ # Belongs to notifiable instance of this subscription as polymorphic association (optional).
22
+ # When present, this subscription is scoped to a specific notifiable instance.
23
+ # When nil, this is a key-level subscription that applies globally.
24
+ # @scope instance
25
+ # @return [Object, nil] Notifiable instance of this subscription
26
+ belongs_to_polymorphic_xdb_record :notifiable, optional: true
27
+
21
28
  field :key, type: String
22
29
  field :subscribing, type: Boolean, default: ActivityNotification.config.subscribe_as_default
23
30
  field :subscribing_to_email, type: Boolean, default: ActivityNotification.config.subscribe_to_email_as_default
@@ -28,7 +35,7 @@ module ActivityNotification
28
35
  field :optional_targets, type: Hash, default: {}
29
36
 
30
37
  validates :target, presence: true
31
- validates :key, presence: true, uniqueness: { scope: [:target_type, :target_id] }
38
+ validates :key, presence: true, uniqueness: { scope: [:target_type, :target_id, :notifiable_type, :notifiable_id] }
32
39
  validates_inclusion_of :subscribing, in: [true, false]
33
40
  validates_inclusion_of :subscribing_to_email, in: [true, false]
34
41
  validate :subscribing_to_email_cannot_be_true_when_subscribing_is_false
@@ -59,6 +66,19 @@ module ActivityNotification
59
66
  # Dummy reload method for test of subscriptions.
60
67
  scope :reload, -> { }
61
68
 
69
+ # Selects key-level subscriptions only (where notifiable is nil).
70
+ # @return [Mongoid::Criteria<Subscription>] Database query of key-level subscriptions
71
+ scope :key_level_only, -> { where(notifiable_type: nil) }
72
+
73
+ # Selects instance-level subscriptions only (where notifiable is present).
74
+ # @return [Mongoid::Criteria<Subscription>] Database query of instance-level subscriptions
75
+ scope :instance_level_only, -> { where(:notifiable_type.ne => nil) }
76
+
77
+ # Selects subscriptions for a specific notifiable instance.
78
+ # @param [Object] notifiable Notifiable instance for filter
79
+ # @return [Mongoid::Criteria<Subscription>] Database query of filtered subscriptions
80
+ scope :for_notifiable, ->(notifiable) { where(notifiable_type: notifiable.class.name, notifiable_id: notifiable.id) }
81
+
62
82
  # Selects unique keys from query for subscriptions.
63
83
  # @return [Array<String>] Array of subscription unique keys
64
84
  def self.uniq_keys
@@ -7,7 +7,7 @@ module ActivityNotification
7
7
  # @scope class
8
8
  # @param [String] name Association name
9
9
  # @param [Object] instance Associated instance
10
- # @return [Mongoid::Criteria<Notificaion>] Database query of filtered notifications
10
+ # @return [Mongoid::Criteria<Notification>] Database query of filtered notifications
11
11
  scope :filtered_by_association, ->(name, instance) { where("#{name}_id" => instance.present? ? instance.id : nil, "#{name}_type" => instance.present? ? instance.class.name : nil) }
12
12
  end
13
13
 
@@ -45,10 +45,10 @@ module ActionDispatch::Routing
45
45
  # open_myscope_user_notification PUT /myscope/users/:user_id/notifications/:id/open(.:format)
46
46
  # { controller:"activity_notification/notifications", action:"open", target_type:"users", routing_scope: :myscope }
47
47
  #
48
- # When you use devise authentication and you want make notification targets assciated with devise,
48
+ # When you use devise authentication and you want to make notification targets associated with devise,
49
49
  # you can create as follows in your routes:
50
50
  # notify_to :users, with_devise: :users
51
- # This with_devise option creates the needed routes assciated with devise authentication:
51
+ # This with_devise option creates the needed routes associated with devise authentication:
52
52
  # # Notification with devise routes
53
53
  # user_notifications GET /users/:user_id/notifications(.:format)
54
54
  # { controller:"activity_notification/notifications_with_devise", action:"index", target_type:"users", devise_type:"users" }
@@ -65,7 +65,7 @@ module ActionDispatch::Routing
65
65
  #
66
66
  # When you use with_devise option and you want to make simple default routes as follows, you can use devise_default_routes option:
67
67
  # notify_to :users, with_devise: :users, devise_default_routes: true
68
- # These with_devise and devise_default_routes options create the needed routes assciated with authenticated devise resource as the default target
68
+ # These with_devise and devise_default_routes options create the needed routes associated with authenticated devise resource as the default target
69
69
  # # Notification with default devise routes
70
70
  # user_notifications GET /notifications(.:format)
71
71
  # { controller:"activity_notification/notifications_with_devise", action:"index", target_type:"users", devise_type:"users" }
@@ -135,7 +135,7 @@ module ActionDispatch::Routing
135
135
  # @param [Symbol] resources Resources to notify
136
136
  # @option options [String] :routing_scope (nil) Routing scope for notification routes
137
137
  # @option options [Symbol] :with_devise (false) Devise resources name for devise integration. Devise integration will be enabled by this option.
138
- # @option options [Boolean] :devise_default_routes (false) Whether you will create routes as device default routes assciated with authenticated devise resource as the default target
138
+ # @option options [Boolean] :devise_default_routes (false) Whether you will create routes as device default routes associated with authenticated devise resource as the default target
139
139
  # @option options [Boolean] :api_mode (false) Whether you will use activity_notification controllers as REST API mode
140
140
  # @option options [Hash|Boolean] :with_subscription (false) Subscription path options to define subscription management paths with notification paths. Calls subscribed_by routing when truthy value is passed as this option.
141
141
  # @option options [String] :model (:notifications) Model name of notifications
@@ -168,7 +168,7 @@ module ActionDispatch::Routing
168
168
 
169
169
  # Includes subscribed_by method for routes, which is responsible to generate all necessary routes for subscriptions of activity_notification.
170
170
  #
171
- # When you have an User model configured as a target (e.g. defined acts_as_target),
171
+ # When you have a User model configured as a target (e.g. defined acts_as_target),
172
172
  # you can create as follows in your routes:
173
173
  # subscribed_by :users
174
174
  # This method creates the needed routes:
@@ -225,10 +225,10 @@ module ActionDispatch::Routing
225
225
  # unsubscribe_to_optional_target_myscope_user_subscription PUT /myscope/users/:user_id/subscriptions/:id/unsubscribe_to_optional_target(.:format)
226
226
  # { controller:"activity_notification/subscriptions", action:"unsubscribe_to_optional_target", target_type:"users", routing_scope: :myscope }
227
227
  #
228
- # When you use devise authentication and you want make subscription targets assciated with devise,
228
+ # When you use devise authentication and you want to make subscription targets associated with devise,
229
229
  # you can create as follows in your routes:
230
230
  # subscribed_by :users, with_devise: :users
231
- # This with_devise option creates the needed routes assciated with devise authentication:
231
+ # This with_devise option creates the needed routes associated with devise authentication:
232
232
  # # Subscription with devise routes
233
233
  # user_subscriptions GET /users/:user_id/subscriptions(.:format)
234
234
  # { controller:"activity_notification/subscriptions_with_devise", action:"index", target_type:"users", devise_type:"users" }
@@ -255,7 +255,7 @@ module ActionDispatch::Routing
255
255
  #
256
256
  # When you use with_devise option and you want to make simple default routes as follows, you can use devise_default_routes option:
257
257
  # subscribed_by :users, with_devise: :users, devise_default_routes: true
258
- # These with_devise and devise_default_routes options create the needed routes assciated with authenticated devise resource as the default target
258
+ # These with_devise and devise_default_routes options create the needed routes associated with authenticated devise resource as the default target
259
259
  # # Subscription with devise routes
260
260
  # user_subscriptions GET /subscriptions(.:format)
261
261
  # { controller:"activity_notification/subscriptions_with_devise", action:"index", target_type:"users", devise_type:"users" }
@@ -331,7 +331,7 @@ module ActionDispatch::Routing
331
331
  # @param [Symbol] resources Resources to notify
332
332
  # @option options [String] :routing_scope (nil) Routing scope for subscription routes
333
333
  # @option options [Symbol] :with_devise (false) Devise resources name for devise integration. Devise integration will be enabled by this option.
334
- # @option options [Boolean] :devise_default_routes (false) Whether you will create routes as device default routes assciated with authenticated devise resource as the default target
334
+ # @option options [Boolean] :devise_default_routes (false) Whether you will create routes as device default routes associated with authenticated devise resource as the default target
335
335
  # @option options [Boolean] :api_mode (false) Whether you will use activity_notification controllers as REST API mode
336
336
  # @option options [String] :model (:subscriptions) Model name of subscriptions
337
337
  # @option options [String] :controller ("activity_notification/subscriptions" | activity_notification/subscriptions_with_devise") :controller option as resources routing
@@ -411,7 +411,7 @@ module ActionDispatch::Routing
411
411
  # @param [Hash] options Passed options from notify_to
412
412
  # @param [Hash] resources_options Options to send resources method
413
413
  def create_notification_routes(options = {}, resources_options = [])
414
- self.resources options[:model], resources_options do
414
+ self.resources options[:model], **resources_options do
415
415
  collection do
416
416
  post :open_all unless ignore_path?(:open_all, options)
417
417
  post :destroy_all unless ignore_path?(:destroy_all, options)
@@ -430,7 +430,7 @@ module ActionDispatch::Routing
430
430
  # @param [Hash] options Passed options from subscribed_by
431
431
  # @param [Hash] resources_options Options to send resources method
432
432
  def create_subscription_routes(options = {}, resources_options = [])
433
- self.resources options[:model], resources_options do
433
+ self.resources options[:model], **resources_options do
434
434
  collection do
435
435
  get :find unless ignore_path?(:find, options)
436
436
  get :optional_target_names if options[:api_mode] && !ignore_path?(:optional_target_names, options)
@@ -9,7 +9,7 @@ module ActivityNotification
9
9
  # == Parameters:
10
10
  # * :printable_name or :printable_notification_group_name
11
11
  # * Printable notification group name.
12
- # This parameter is a optional since `ActivityNotification::Common.printable_name` is used as default value.
12
+ # This parameter is optional since `ActivityNotification::Common.printable_name` is used as default value.
13
13
  # :printable_name is the same option as :printable_notification_group_name
14
14
  # @example Define printable name with article title
15
15
  # # app/models/article.rb
@@ -14,8 +14,8 @@ module ActivityNotification
14
14
  # == Parameters:
15
15
  # * :targets
16
16
  # * Targets to send notifications.
17
- # It it set as ActiveRecord records or array of models.
18
- # This is a only necessary option.
17
+ # It is set as ActiveRecord records or array of models.
18
+ # This is the only necessary option.
19
19
  # If you do not specify this option, you have to override notification_targets
20
20
  # or notification_[plural target type] (e.g. notification_users) method.
21
21
  # @example Notify to all users
@@ -189,10 +189,10 @@ module ActivityNotification
189
189
  # end
190
190
  #
191
191
  # * :optional_targets
192
- # * Optional targets to integrate external notification serveces like Amazon SNS or Slack.
192
+ # * Optional targets to integrate external notification services like Amazon SNS or Slack.
193
193
  # You can use hash of optional target implementation class as key and initializing parameters as value for this parameter.
194
194
  # When the hash parameter is passed, acts_as_notifiable will create new instance of optional target class and call initialize_target method with initializing parameters, then configure them as optional_targets for this notifiable and target.
195
- # You can also use symbol of method name or lambda function which returns array of initialized optional target intstances.
195
+ # You can also use symbol of method name or lambda function which returns array of initialized optional target instances.
196
196
  # All optional target class must extends ActivityNotification::OptionalTarget::Base.
197
197
  # This parameter is completely optional.
198
198
  # @example Define to integrate with Amazon SNS, Slack and your custom ConsoleOutput targets
@@ -203,7 +203,7 @@ module ActivityNotification
203
203
  # require 'custom_optional_targets/console_output'
204
204
  # acts_as_notifiable :admins, targets: Admin.all,
205
205
  # optional_targets: {
206
- # ActivityNotification::OptionalTarget::AmazonSNS => { topic_arn: '<Topin ARN of yours>' },
206
+ # ActivityNotification::OptionalTarget::AmazonSNS => { topic_arn: '<Topic ARN of yours>' },
207
207
  # ActivityNotification::OptionalTarget::Slack => {
208
208
  # webhook_url: '<Slack Webhook URL>',
209
209
  # slack_name: :slack_name, channel: 'activity_notification', username: 'ActivityNotification', icon_emoji: ":ghost:"
@@ -9,7 +9,7 @@ module ActivityNotification
9
9
  # == Parameters:
10
10
  # * :printable_name or :printable_notifier_name
11
11
  # * Printable notifier name.
12
- # This parameter is a optional since `ActivityNotification::Common.printable_name` is used as default value.
12
+ # This parameter is optional since `ActivityNotification::Common.printable_name` is used as default value.
13
13
  # :printable_name is the same option as :printable_notifier_name
14
14
  # @example Define printable name with user name of name field
15
15
  # # app/models/user.rb
@@ -9,7 +9,7 @@ module ActivityNotification
9
9
  # == Parameters:
10
10
  # * :email
11
11
  # * Email address to send notification email.
12
- # This is a necessary option when you enables email notification.
12
+ # This is a necessary option when you enable email notification.
13
13
  # @example Simply use :email field
14
14
  # # app/models/user.rb
15
15
  # class User < ActiveRecord::Base
@@ -1,3 +1,3 @@
1
1
  module ActivityNotification
2
- VERSION = "2.5.1"
2
+ VERSION = "2.6.0"
3
3
  end
@@ -0,0 +1,23 @@
1
+ require 'rails/generators/active_record'
2
+
3
+ module ActivityNotification
4
+ module Generators
5
+ # Migration generator to add notifiable columns to subscriptions table
6
+ # for instance-level subscription support.
7
+ # @example Run migration generator
8
+ # rails generate activity_notification:add_notifiable_to_subscriptions
9
+ class AddNotifiableToSubscriptionsGenerator < ActiveRecord::Generators::Base
10
+ source_root File.expand_path("templates", __dir__)
11
+
12
+ argument :name, type: :string, default: 'AddNotifiableToSubscriptions',
13
+ desc: "The migration name"
14
+
15
+ # Create migration file in application directory
16
+ def create_migration_file
17
+ @migration_name = name
18
+ migration_template 'add_notifiable_to_subscriptions.rb',
19
+ "db/migrate/#{name.underscore}.rb"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,13 @@
1
+ # Migration to add notifiable polymorphic columns to subscriptions table
2
+ # for instance-level subscription support.
3
+ class <%= @migration_name %> < ActiveRecord::Migration<%= "[#{Rails.version.to_f}]" %>
4
+ def change
5
+ add_reference :subscriptions, :notifiable, polymorphic: true, index: true
6
+
7
+ # Replace the old unique index with one that includes notifiable columns
8
+ remove_index :subscriptions, [:target_type, :target_id, :key]
9
+ add_index :subscriptions, [:target_type, :target_id, :key, :notifiable_type, :notifiable_id],
10
+ unique: true, name: 'index_subscriptions_uniqueness',
11
+ length: { target_type: 191, key: 191, notifiable_type: 191 }
12
+ end
13
+ end
@@ -38,7 +38,7 @@ ActivityNotification.configure do |config|
38
38
 
39
39
  # Configure default optional target subscription value to use when the subscription record does not configured.
40
40
  # Note that you can configure them for each method calling as default argument.
41
- # Set false when you want to unsubscribe to optinal target notifications as default.
41
+ # Set false when you want to unsubscribe to optional target notifications as default.
42
42
  # config.subscribe_to_optional_targets_as_default = true
43
43
 
44
44
  # Configure the e-mail address which will be shown in ActivityNotification::Mailer,
@@ -53,6 +53,18 @@ ActivityNotification.configure do |config|
53
53
  # config.mailer_cc = ['admin@example.com', 'support@example.com']
54
54
  # config.mailer_cc = ->(key){ key.include?('urgent') ? 'urgent@example.com' : nil }
55
55
 
56
+ # Configure default attachment(s) for notification emails.
57
+ # Attachments are specified as Hash with :filename and :content (binary) or :path (file path).
58
+ # Optional :mime_type is inferred from filename if not provided.
59
+ # Can be overridden per target by defining a mailer_attachments method in the target model,
60
+ # or per notification by defining overriding_notification_email_attachments in the notifiable model.
61
+ # config.mailer_attachments = { filename: 'terms.pdf', path: Rails.root.join('public', 'terms.pdf') }
62
+ # config.mailer_attachments = [
63
+ # { filename: 'logo.png', path: Rails.root.join('app/assets/images/logo.png') },
64
+ # { filename: 'terms.pdf', content: File.read(Rails.root.join('public', 'terms.pdf')) }
65
+ # ]
66
+ # config.mailer_attachments = ->(key) { key.include?('invoice') ? { filename: 'invoice.pdf', content: generate_pdf } : nil }
67
+
56
68
  # Configure the class responsible to send e-mails.
57
69
  # config.mailer = "ActivityNotification::Mailer"
58
70
 
@@ -80,7 +92,7 @@ ActivityNotification.configure do |config|
80
92
  # Configure delimiter of composite key for DynamoDB.
81
93
  # config.composite_key_delimiter = '#'
82
94
 
83
- # Configure if activity_notification stores notificaion records including associated records like target and notifiable..
95
+ # Configure if activity_notification stores notification records including associated records like target and notifiable..
84
96
  # This store_with_associated_records option can be set true only when you use mongoid or dynamoid ORM.
85
97
  config.store_with_associated_records = false
86
98
 
@@ -28,6 +28,7 @@ class <%= @migration_name %> < ActiveRecord::Migration<%= "[#{Rails.version.to_f
28
28
 
29
29
  <% if @migration_tables.include?('subscriptions') %>create_table :subscriptions do |t|
30
30
  t.belongs_to :target, polymorphic: true, index: true, null: false
31
+ t.belongs_to :notifiable, polymorphic: true, index: true
31
32
  t.string :key, index: true, null: false
32
33
  t.boolean :subscribing, null: false, default: true
33
34
  t.boolean :subscribing_to_email, null: false, default: true
@@ -39,8 +40,9 @@ class <%= @migration_name %> < ActiveRecord::Migration<%= "[#{Rails.version.to_f
39
40
 
40
41
  t.timestamps null: false
41
42
  end
42
- add_index :subscriptions, [:target_type, :target_id, :key], unique: true<% else %># create_table :subscriptions do |t|
43
+ add_index :subscriptions, [:target_type, :target_id, :key, :notifiable_type, :notifiable_id], unique: true, name: 'index_subscriptions_uniqueness', length: { target_type: 191, key: 191, notifiable_type: 191 }<% else %># create_table :subscriptions do |t|
43
44
  # t.belongs_to :target, polymorphic: true, index: true, null: false
45
+ # t.belongs_to :notifiable, polymorphic: true, index: true
44
46
  # t.string :key, index: true, null: false
45
47
  # t.boolean :subscribing, null: false, default: true
46
48
  # t.boolean :subscribing_to_email, null: false, default: true
@@ -52,6 +54,6 @@ class <%= @migration_name %> < ActiveRecord::Migration<%= "[#{Rails.version.to_f
52
54
  #
53
55
  # t.timestamps null: false
54
56
  # end
55
- # add_index :subscriptions, [:target_type, :target_id, :key], unique: true<% end %>
57
+ # add_index :subscriptions, [:target_type, :target_id, :key, :notifiable_type, :notifiable_id], unique: true, name: 'index_subscriptions_uniqueness', length: { target_type: 191, key: 191, notifiable_type: 191 }<% end %>
56
58
  end
57
59
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activity_notification
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.1
4
+ version: 2.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shota Yamazaki
@@ -371,6 +371,7 @@ files:
371
371
  - docs/Functions.md
372
372
  - docs/Setup.md
373
373
  - docs/Testing.md
374
+ - docs/Upgrade-to-2.6.md
374
375
  - lib/activity_notification.rb
375
376
  - lib/activity_notification/apis/cascading_notification_api.rb
376
377
  - lib/activity_notification/apis/notification_api.rb
@@ -428,6 +429,8 @@ files:
428
429
  - lib/activity_notification/roles/acts_as_notifier.rb
429
430
  - lib/activity_notification/roles/acts_as_target.rb
430
431
  - lib/activity_notification/version.rb
432
+ - lib/generators/activity_notification/add_notifiable_to_subscriptions/add_notifiable_to_subscriptions_generator.rb
433
+ - lib/generators/activity_notification/add_notifiable_to_subscriptions/templates/add_notifiable_to_subscriptions.rb
431
434
  - lib/generators/activity_notification/controllers_generator.rb
432
435
  - lib/generators/activity_notification/install_generator.rb
433
436
  - lib/generators/activity_notification/migration/migration_generator.rb
@@ -461,7 +464,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
461
464
  requirements:
462
465
  - - ">="
463
466
  - !ruby/object:Gem::Version
464
- version: 2.1.0
467
+ version: 2.7.0
465
468
  required_rubygems_version: !ruby/object:Gem::Requirement
466
469
  requirements:
467
470
  - - ">="