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.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/app/channels/activity_notification/notification_api_channel.rb +5 -5
- data/app/channels/activity_notification/notification_api_with_devise_channel.rb +4 -4
- data/app/channels/activity_notification/notification_channel.rb +4 -0
- data/app/channels/activity_notification/notification_with_devise_channel.rb +4 -4
- data/app/controllers/activity_notification/notifications_controller.rb +1 -2
- data/app/controllers/activity_notification/subscriptions_controller.rb +2 -3
- data/app/jobs/activity_notification/notify_all_job.rb +2 -2
- data/app/jobs/activity_notification/notify_job.rb +2 -2
- data/app/jobs/activity_notification/notify_to_job.rb +1 -1
- data/app/mailers/activity_notification/mailer.rb +1 -1
- data/app/views/activity_notification/mailer/default/batch_default.text.erb +1 -1
- data/app/views/activity_notification/notifications/default/index.html.erb +1 -1
- data/app/views/activity_notification/subscriptions/default/_notification_keys.html.erb +1 -1
- data/app/views/activity_notification/subscriptions/default/_subscription.html.erb +1 -1
- data/docs/Functions.md +93 -9
- data/docs/Setup.md +7 -7
- data/docs/Testing.md +1 -1
- data/docs/Upgrade-to-2.6.md +108 -0
- data/lib/activity_notification/apis/notification_api.rb +55 -40
- data/lib/activity_notification/apis/subscription_api.rb +10 -10
- data/lib/activity_notification/common.rb +5 -5
- data/lib/activity_notification/config.rb +15 -5
- data/lib/activity_notification/controllers/common_controller.rb +2 -4
- data/lib/activity_notification/controllers/devise_authentication_controller.rb +2 -2
- data/lib/activity_notification/helpers/polymorphic_helpers.rb +6 -6
- data/lib/activity_notification/helpers/view_helpers.rb +3 -3
- data/lib/activity_notification/mailers/helpers.rb +88 -2
- data/lib/activity_notification/models/concerns/notifiable.rb +60 -30
- data/lib/activity_notification/models/concerns/notifier.rb +1 -1
- data/lib/activity_notification/models/concerns/subscriber.rb +72 -15
- data/lib/activity_notification/models/concerns/target.rb +38 -35
- data/lib/activity_notification/optional_targets/action_cable_api_channel.rb +1 -1
- data/lib/activity_notification/optional_targets/slack.rb +2 -2
- data/lib/activity_notification/orm/active_record/notification.rb +25 -25
- data/lib/activity_notification/orm/active_record/subscription.rb +21 -1
- data/lib/activity_notification/orm/dynamoid/extension.rb +3 -3
- data/lib/activity_notification/orm/dynamoid/subscription.rb +8 -1
- data/lib/activity_notification/orm/dynamoid.rb +18 -18
- data/lib/activity_notification/orm/mongoid/notification.rb +26 -28
- data/lib/activity_notification/orm/mongoid/subscription.rb +21 -1
- data/lib/activity_notification/orm/mongoid.rb +1 -1
- data/lib/activity_notification/rails/routes.rb +11 -11
- data/lib/activity_notification/roles/acts_as_group.rb +1 -1
- data/lib/activity_notification/roles/acts_as_notifiable.rb +5 -5
- data/lib/activity_notification/roles/acts_as_notifier.rb +1 -1
- data/lib/activity_notification/roles/acts_as_target.rb +1 -1
- data/lib/activity_notification/version.rb +1 -1
- data/lib/generators/activity_notification/add_notifiable_to_subscriptions/add_notifiable_to_subscriptions_generator.rb +23 -0
- data/lib/generators/activity_notification/add_notifiable_to_subscriptions/templates/add_notifiable_to_subscriptions.rb +13 -0
- data/lib/generators/templates/activity_notification.rb +14 -2
- data/lib/generators/templates/migrations/migration.rb +4 -2
- 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
|
-
#
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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<
|
|
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
|
|
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<
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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<
|
|
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<
|
|
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<
|
|
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<
|
|
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<
|
|
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<
|
|
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<
|
|
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<
|
|
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<
|
|
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<
|
|
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<
|
|
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
|
|
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<
|
|
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
|
|
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<
|
|
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
|
|
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<
|
|
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
|
|
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<
|
|
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<
|
|
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<
|
|
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<
|
|
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<
|
|
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<
|
|
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<
|
|
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<
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
18
|
-
# This is
|
|
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
|
|
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
|
|
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: '<
|
|
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
|
|
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
|
|
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
|
|
@@ -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
|
|
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
|
|
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.
|
|
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.
|
|
467
|
+
version: 2.7.0
|
|
465
468
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
466
469
|
requirements:
|
|
467
470
|
- - ">="
|