activity_notification 2.4.1 → 2.5.1
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 +4 -2
- data/app/jobs/activity_notification/cascading_notification_job.rb +123 -0
- data/docs/Functions.md +197 -1
- data/lib/activity_notification/apis/cascading_notification_api.rb +208 -0
- data/lib/activity_notification/apis/notification_api.rb +78 -5
- data/lib/activity_notification/config.rb +10 -0
- data/lib/activity_notification/mailers/helpers.rb +27 -1
- data/lib/activity_notification/version.rb +1 -1
- data/lib/generators/templates/activity_notification.rb +8 -0
- metadata +8 -447
- data/.codeclimate.yml +0 -33
- data/.coveralls.yml +0 -1
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -22
- data/.github/ISSUE_TEMPLATE/feature_request.md +0 -17
- data/.github/pull_request_template.md +0 -13
- data/.github/workflows/build.yml +0 -100
- data/.gitignore +0 -74
- data/.rspec +0 -3
- data/.rubocop.yml +0 -1157
- data/.yardopts +0 -6
- data/CHANGELOG.md +0 -452
- data/Gemfile +0 -31
- data/Procfile +0 -2
- data/Rakefile +0 -28
- data/activity_notification.gemspec +0 -44
- data/ai-curated-specs/issues/172/design.md +0 -220
- data/ai-curated-specs/issues/172/tasks.md +0 -326
- data/ai-curated-specs/issues/188/design.md +0 -227
- data/ai-curated-specs/issues/188/requirements.md +0 -78
- data/ai-curated-specs/issues/188/tasks.md +0 -203
- data/ai-curated-specs/issues/188/upstream-contributions.md +0 -592
- data/ai-curated-specs/issues/50/design.md +0 -235
- data/ai-curated-specs/issues/50/requirements.md +0 -49
- data/ai-curated-specs/issues/50/tasks.md +0 -232
- data/bin/_dynamodblocal +0 -4
- data/bin/bundle_update.sh +0 -7
- data/bin/deploy_on_heroku.sh +0 -16
- data/bin/install_dynamodblocal.sh +0 -5
- data/bin/start_dynamodblocal.sh +0 -47
- data/bin/stop_dynamodblocal.sh +0 -34
- data/gemfiles/Gemfile.rails-5.0 +0 -25
- data/gemfiles/Gemfile.rails-5.1 +0 -25
- data/gemfiles/Gemfile.rails-5.2 +0 -24
- data/gemfiles/Gemfile.rails-6.0 +0 -23
- data/gemfiles/Gemfile.rails-6.1 +0 -22
- data/gemfiles/Gemfile.rails-7.0 +0 -25
- data/gemfiles/Gemfile.rails-7.1 +0 -23
- data/gemfiles/Gemfile.rails-7.2 +0 -23
- data/gemfiles/Gemfile.rails-8.0 +0 -24
- data/package.json +0 -8
- data/spec/channels/notification_api_channel_shared_examples.rb +0 -59
- data/spec/channels/notification_api_channel_spec.rb +0 -49
- data/spec/channels/notification_api_with_devise_channel_spec.rb +0 -76
- data/spec/channels/notification_channel_shared_examples.rb +0 -59
- data/spec/channels/notification_channel_spec.rb +0 -48
- data/spec/channels/notification_with_devise_channel_spec.rb +0 -97
- data/spec/concerns/apis/notification_api_spec.rb +0 -1627
- data/spec/concerns/apis/subscription_api_spec.rb +0 -474
- data/spec/concerns/common_spec.rb +0 -213
- data/spec/concerns/models/group_spec.rb +0 -61
- data/spec/concerns/models/notifiable_spec.rb +0 -782
- data/spec/concerns/models/notifier_spec.rb +0 -71
- data/spec/concerns/models/subscriber_spec.rb +0 -800
- data/spec/concerns/models/target_spec.rb +0 -1285
- data/spec/concerns/renderable_spec.rb +0 -129
- data/spec/config_spec.rb +0 -85
- data/spec/controllers/common_controller_spec.rb +0 -25
- data/spec/controllers/controller_spec_utility.rb +0 -100
- data/spec/controllers/dummy_common_controller.rb +0 -5
- data/spec/controllers/notifications_api_controller_shared_examples.rb +0 -619
- data/spec/controllers/notifications_api_controller_spec.rb +0 -19
- data/spec/controllers/notifications_api_with_devise_controller_spec.rb +0 -60
- data/spec/controllers/notifications_controller_shared_examples.rb +0 -743
- data/spec/controllers/notifications_controller_spec.rb +0 -11
- data/spec/controllers/notifications_with_devise_controller_spec.rb +0 -97
- data/spec/controllers/subscriptions_api_controller_shared_examples.rb +0 -750
- data/spec/controllers/subscriptions_api_controller_spec.rb +0 -19
- data/spec/controllers/subscriptions_api_with_devise_controller_spec.rb +0 -60
- data/spec/controllers/subscriptions_controller_shared_examples.rb +0 -946
- data/spec/controllers/subscriptions_controller_spec.rb +0 -11
- data/spec/controllers/subscriptions_with_devise_controller_spec.rb +0 -97
- data/spec/factories/admins.rb +0 -5
- data/spec/factories/articles.rb +0 -5
- data/spec/factories/comments.rb +0 -6
- data/spec/factories/dummy/dummy_group.rb +0 -4
- data/spec/factories/dummy/dummy_notifiable.rb +0 -4
- data/spec/factories/dummy/dummy_notifier.rb +0 -4
- data/spec/factories/dummy/dummy_subscriber.rb +0 -4
- data/spec/factories/dummy/dummy_target.rb +0 -4
- data/spec/factories/notifications.rb +0 -7
- data/spec/factories/subscriptions.rb +0 -8
- data/spec/factories/users.rb +0 -11
- data/spec/generators/controllers_generator_spec.rb +0 -85
- data/spec/generators/install_generator_spec.rb +0 -43
- data/spec/generators/migration/migration_generator_spec.rb +0 -80
- data/spec/generators/models_generator_spec.rb +0 -96
- data/spec/generators/views_generator_spec.rb +0 -195
- data/spec/helpers/polymorphic_helpers_spec.rb +0 -89
- data/spec/helpers/view_helpers_spec.rb +0 -547
- data/spec/jobs/notification_resilience_job_spec.rb +0 -167
- data/spec/jobs/notify_all_job_spec.rb +0 -23
- data/spec/jobs/notify_job_spec.rb +0 -23
- data/spec/jobs/notify_to_job_spec.rb +0 -23
- data/spec/mailers/mailer_spec.rb +0 -214
- data/spec/mailers/notification_resilience_spec.rb +0 -263
- data/spec/models/dummy/dummy_group_spec.rb +0 -10
- data/spec/models/dummy/dummy_notifiable_spec.rb +0 -10
- data/spec/models/dummy/dummy_notifier_spec.rb +0 -10
- data/spec/models/dummy/dummy_subscriber_spec.rb +0 -8
- data/spec/models/dummy/dummy_target_spec.rb +0 -10
- data/spec/models/notification_spec.rb +0 -472
- data/spec/models/subscription_spec.rb +0 -215
- data/spec/optional_targets/action_cable_api_channel_spec.rb +0 -34
- data/spec/optional_targets/action_cable_channel_spec.rb +0 -41
- data/spec/optional_targets/amazon_sns_spec.rb +0 -47
- data/spec/optional_targets/base_spec.rb +0 -45
- data/spec/optional_targets/slack_spec.rb +0 -44
- data/spec/orm/dynamoid_spec.rb +0 -115
- data/spec/rails_app/Rakefile +0 -15
- data/spec/rails_app/app/assets/config/manifest.js +0 -3
- data/spec/rails_app/app/assets/images/.keep +0 -0
- data/spec/rails_app/app/assets/javascripts/application.js +0 -3
- data/spec/rails_app/app/assets/javascripts/cable.js +0 -12
- data/spec/rails_app/app/assets/stylesheets/application.css +0 -15
- data/spec/rails_app/app/assets/stylesheets/reset.css +0 -85
- data/spec/rails_app/app/assets/stylesheets/style.css +0 -244
- data/spec/rails_app/app/controllers/admins_controller.rb +0 -21
- data/spec/rails_app/app/controllers/application_controller.rb +0 -5
- data/spec/rails_app/app/controllers/articles_controller.rb +0 -67
- data/spec/rails_app/app/controllers/comments_controller.rb +0 -36
- data/spec/rails_app/app/controllers/concerns/.keep +0 -0
- data/spec/rails_app/app/controllers/spa_controller.rb +0 -7
- data/spec/rails_app/app/controllers/users/notifications_controller.rb +0 -2
- data/spec/rails_app/app/controllers/users/notifications_with_devise_controller.rb +0 -2
- data/spec/rails_app/app/controllers/users/subscriptions_controller.rb +0 -2
- data/spec/rails_app/app/controllers/users/subscriptions_with_devise_controller.rb +0 -2
- data/spec/rails_app/app/controllers/users_controller.rb +0 -26
- data/spec/rails_app/app/helpers/application_helper.rb +0 -2
- data/spec/rails_app/app/helpers/devise_helper.rb +0 -2
- data/spec/rails_app/app/javascript/App.vue +0 -40
- data/spec/rails_app/app/javascript/components/DeviseTokenAuth.vue +0 -82
- data/spec/rails_app/app/javascript/components/Top.vue +0 -98
- data/spec/rails_app/app/javascript/components/notifications/Index.vue +0 -200
- data/spec/rails_app/app/javascript/components/notifications/Notification.vue +0 -133
- data/spec/rails_app/app/javascript/components/notifications/NotificationContent.vue +0 -122
- data/spec/rails_app/app/javascript/components/subscriptions/Index.vue +0 -279
- data/spec/rails_app/app/javascript/components/subscriptions/NewSubscription.vue +0 -112
- data/spec/rails_app/app/javascript/components/subscriptions/NotificationKey.vue +0 -141
- data/spec/rails_app/app/javascript/components/subscriptions/Subscription.vue +0 -226
- data/spec/rails_app/app/javascript/config/development.js +0 -5
- data/spec/rails_app/app/javascript/config/environment.js +0 -7
- data/spec/rails_app/app/javascript/config/production.js +0 -5
- data/spec/rails_app/app/javascript/config/test.js +0 -5
- data/spec/rails_app/app/javascript/packs/application.js +0 -18
- data/spec/rails_app/app/javascript/packs/spa.js +0 -14
- data/spec/rails_app/app/javascript/router/index.js +0 -73
- data/spec/rails_app/app/javascript/store/index.js +0 -37
- data/spec/rails_app/app/mailers/.keep +0 -0
- data/spec/rails_app/app/mailers/custom_notification_mailer.rb +0 -5
- data/spec/rails_app/app/models/admin.rb +0 -35
- data/spec/rails_app/app/models/article.rb +0 -54
- data/spec/rails_app/app/models/comment.rb +0 -81
- data/spec/rails_app/app/models/dummy/dummy_base.rb +0 -11
- data/spec/rails_app/app/models/dummy/dummy_group.rb +0 -23
- data/spec/rails_app/app/models/dummy/dummy_notifiable.rb +0 -15
- data/spec/rails_app/app/models/dummy/dummy_notifiable_target.rb +0 -27
- data/spec/rails_app/app/models/dummy/dummy_notifier.rb +0 -15
- data/spec/rails_app/app/models/dummy/dummy_subscriber.rb +0 -14
- data/spec/rails_app/app/models/dummy/dummy_target.rb +0 -16
- data/spec/rails_app/app/models/user.rb +0 -73
- data/spec/rails_app/app/views/activity_notification/mailer/dummy_subscribers/test_key.text.erb +0 -1
- data/spec/rails_app/app/views/activity_notification/notifications/default/article/_update.html.erb +0 -146
- data/spec/rails_app/app/views/activity_notification/notifications/default/custom/_path_test.html.erb +0 -1
- data/spec/rails_app/app/views/activity_notification/notifications/default/custom/_test.html.erb +0 -1
- data/spec/rails_app/app/views/activity_notification/notifications/users/_custom_index.html.erb +0 -1
- data/spec/rails_app/app/views/activity_notification/notifications/users/custom/_test.html.erb +0 -1
- data/spec/rails_app/app/views/activity_notification/notifications/users/overridden/custom/_test.html.erb +0 -1
- data/spec/rails_app/app/views/activity_notification/optional_targets/admins/amazon_sns/comment/_default.text.erb +0 -10
- data/spec/rails_app/app/views/articles/_form.html.erb +0 -24
- data/spec/rails_app/app/views/articles/edit.html.erb +0 -8
- data/spec/rails_app/app/views/articles/index.html.erb +0 -113
- data/spec/rails_app/app/views/articles/new.html.erb +0 -7
- data/spec/rails_app/app/views/articles/show.html.erb +0 -49
- data/spec/rails_app/app/views/layouts/_header.html.erb +0 -46
- data/spec/rails_app/app/views/layouts/application.html.erb +0 -15
- data/spec/rails_app/app/views/spa/index.html.erb +0 -2
- data/spec/rails_app/babel.config.js +0 -72
- data/spec/rails_app/bin/bundle +0 -3
- data/spec/rails_app/bin/rails +0 -4
- data/spec/rails_app/bin/rake +0 -4
- data/spec/rails_app/bin/setup +0 -29
- data/spec/rails_app/bin/webpack +0 -18
- data/spec/rails_app/bin/webpack-dev-server +0 -18
- data/spec/rails_app/config/application.rb +0 -54
- data/spec/rails_app/config/boot.rb +0 -5
- data/spec/rails_app/config/cable.yml +0 -8
- data/spec/rails_app/config/database.yml +0 -36
- data/spec/rails_app/config/dynamoid.rb +0 -13
- data/spec/rails_app/config/environment.rb +0 -26
- data/spec/rails_app/config/environments/development.rb +0 -60
- data/spec/rails_app/config/environments/production.rb +0 -85
- data/spec/rails_app/config/environments/test.rb +0 -53
- data/spec/rails_app/config/initializers/activity_notification.rb +0 -104
- data/spec/rails_app/config/initializers/assets.rb +0 -11
- data/spec/rails_app/config/initializers/backtrace_silencers.rb +0 -7
- data/spec/rails_app/config/initializers/cookies_serializer.rb +0 -3
- data/spec/rails_app/config/initializers/copy_it.aws.rb.template +0 -6
- data/spec/rails_app/config/initializers/devise.rb +0 -278
- data/spec/rails_app/config/initializers/devise_token_auth.rb +0 -55
- data/spec/rails_app/config/initializers/filter_parameter_logging.rb +0 -4
- data/spec/rails_app/config/initializers/inflections.rb +0 -16
- data/spec/rails_app/config/initializers/mime_types.rb +0 -4
- data/spec/rails_app/config/initializers/mysql.rb +0 -9
- data/spec/rails_app/config/initializers/session_store.rb +0 -3
- data/spec/rails_app/config/initializers/wrap_parameters.rb +0 -14
- data/spec/rails_app/config/initializers/zeitwerk.rb +0 -10
- data/spec/rails_app/config/locales/activity_notification.en.yml +0 -26
- data/spec/rails_app/config/locales/devise.en.yml +0 -62
- data/spec/rails_app/config/mongoid.yml +0 -13
- data/spec/rails_app/config/routes.rb +0 -50
- data/spec/rails_app/config/secrets.yml +0 -22
- data/spec/rails_app/config/webpack/development.js +0 -5
- data/spec/rails_app/config/webpack/environment.js +0 -7
- data/spec/rails_app/config/webpack/loaders/vue.js +0 -6
- data/spec/rails_app/config/webpack/production.js +0 -5
- data/spec/rails_app/config/webpack/test.js +0 -5
- data/spec/rails_app/config/webpacker.yml +0 -97
- data/spec/rails_app/config.ru +0 -4
- data/spec/rails_app/db/migrate/20160716000000_create_test_tables.rb +0 -42
- data/spec/rails_app/db/migrate/20181209000000_create_activity_notification_tables.rb +0 -33
- data/spec/rails_app/db/migrate/20191201000000_add_tokens_to_users.rb +0 -10
- data/spec/rails_app/db/schema.rb +0 -98
- data/spec/rails_app/db/seeds.rb +0 -95
- data/spec/rails_app/lib/custom_optional_targets/console_output.rb +0 -16
- data/spec/rails_app/lib/custom_optional_targets/raise_error.rb +0 -14
- data/spec/rails_app/lib/custom_optional_targets/wrong_target.rb +0 -13
- data/spec/rails_app/lib/mailer_previews/mailer_preview.rb +0 -29
- data/spec/rails_app/package.json +0 -23
- data/spec/rails_app/postcss.config.js +0 -12
- data/spec/rails_app/public/404.html +0 -67
- data/spec/rails_app/public/422.html +0 -67
- data/spec/rails_app/public/500.html +0 -66
- data/spec/rails_app/public/favicon.ico +0 -0
- data/spec/roles/acts_as_group_spec.rb +0 -30
- data/spec/roles/acts_as_notifiable_spec.rb +0 -432
- data/spec/roles/acts_as_notifier_spec.rb +0 -30
- data/spec/roles/acts_as_target_spec.rb +0 -36
- data/spec/spec_helper.rb +0 -56
- data/spec/version_spec.rb +0 -31
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
require 'activity_notification/apis/cascading_notification_api'
|
|
2
|
+
|
|
1
3
|
module ActivityNotification
|
|
2
4
|
# Defines API for notification included in Notification model.
|
|
3
5
|
module NotificationApi
|
|
4
6
|
extend ActiveSupport::Concern
|
|
7
|
+
include CascadingNotificationApi
|
|
5
8
|
|
|
6
9
|
included do
|
|
7
10
|
# Defines store_notification as private clas method
|
|
@@ -228,7 +231,8 @@ module ActivityNotification
|
|
|
228
231
|
notify_later(target_type, notifiable, options)
|
|
229
232
|
else
|
|
230
233
|
targets = notifiable.notification_targets(target_type, options[:pass_full_options] ? options : options[:key])
|
|
231
|
-
|
|
234
|
+
# Optimize blank check to avoid loading all records for ActiveRecord relations
|
|
235
|
+
unless targets_empty?(targets)
|
|
232
236
|
notify_all(targets, notifiable, options)
|
|
233
237
|
end
|
|
234
238
|
end
|
|
@@ -269,10 +273,17 @@ module ActivityNotification
|
|
|
269
273
|
|
|
270
274
|
# Generates notifications to specified targets.
|
|
271
275
|
#
|
|
272
|
-
#
|
|
276
|
+
# For large target collections, this method uses batch processing to reduce memory consumption:
|
|
277
|
+
# - ActiveRecord::Relation: Uses find_each (loads in batches of 1000 records)
|
|
278
|
+
# - Mongoid::Criteria: Uses each with cursor batching
|
|
279
|
+
# - Arrays: Standard iteration (already in memory)
|
|
280
|
+
#
|
|
281
|
+
# @example Notify to all users (with ActiveRecord relation for memory efficiency)
|
|
273
282
|
# ActivityNotification::Notification.notify_all User.all, @comment
|
|
283
|
+
# @example Notify to all users with custom batch size
|
|
284
|
+
# ActivityNotification::Notification.notify_all User.all, @comment, batch_size: 500
|
|
274
285
|
#
|
|
275
|
-
# @param [Array<Object>] targets Targets to send notifications
|
|
286
|
+
# @param [ActiveRecord::Relation, Mongoid::Criteria, Array<Object>] targets Targets to send notifications
|
|
276
287
|
# @param [Object] notifiable Notifiable instance
|
|
277
288
|
# @param [Hash] options Options for notifications
|
|
278
289
|
# @option options [String] :key (notifiable.default_notification_key) Key of the notification
|
|
@@ -284,23 +295,32 @@ module ActivityNotification
|
|
|
284
295
|
# @option options [Boolean] :send_email (true) Whether it sends notification email
|
|
285
296
|
# @option options [Boolean] :send_later (true) Whether it sends notification email asynchronously
|
|
286
297
|
# @option options [Boolean] :publish_optional_targets (true) Whether it publishes notification to optional targets
|
|
298
|
+
# @option options [Integer] :batch_size (1000) Batch size for ActiveRecord find_each (optional)
|
|
287
299
|
# @option options [Hash<String, Hash>] :optional_targets ({}) Options for optional targets, keys are optional target name (:amazon_sns or :slack etc) and values are options
|
|
288
300
|
# @return [Array<Notificaion>] Array of generated notifications
|
|
289
301
|
def notify_all(targets, notifiable, options = {})
|
|
290
302
|
if options[:notify_later]
|
|
291
303
|
notify_all_later(targets, notifiable, options)
|
|
292
304
|
else
|
|
293
|
-
|
|
305
|
+
# Optimize for large ActiveRecord relations by using batch processing
|
|
306
|
+
process_targets_in_batches(targets, notifiable, options)
|
|
294
307
|
end
|
|
295
308
|
end
|
|
296
309
|
alias_method :notify_all_now, :notify_all
|
|
297
310
|
|
|
298
311
|
# Generates notifications to specified targets later by ActiveJob queue.
|
|
299
312
|
#
|
|
313
|
+
# Note: When passing ActiveRecord relations or Mongoid criteria to async jobs,
|
|
314
|
+
# they may be serialized to arrays before job execution, which can consume memory
|
|
315
|
+
# for large target sets. For very large datasets (10,000+ records), consider using
|
|
316
|
+
# notify_later with target_type instead, which generates notifications asynchronously
|
|
317
|
+
# without loading all targets upfront:
|
|
318
|
+
# ActivityNotification::Notification.notify(:users, @comment, notify_later: true)
|
|
319
|
+
#
|
|
300
320
|
# @example Notify to all users later
|
|
301
321
|
# ActivityNotification::Notification.notify_all_later User.all, @comment
|
|
302
322
|
#
|
|
303
|
-
# @param [Array<Object>] targets Targets to send notifications
|
|
323
|
+
# @param [ActiveRecord::Relation, Mongoid::Criteria, Array<Object>] targets Targets to send notifications
|
|
304
324
|
# @param [Object] notifiable Notifiable instance
|
|
305
325
|
# @param [Hash] options Options for notifications
|
|
306
326
|
# @option options [String] :key (notifiable.default_notification_key) Key of the notification
|
|
@@ -546,6 +566,59 @@ module ActivityNotification
|
|
|
546
566
|
notification.after_store
|
|
547
567
|
notification
|
|
548
568
|
end
|
|
569
|
+
|
|
570
|
+
# Checks if targets collection is empty without loading all records
|
|
571
|
+
# @api private
|
|
572
|
+
# @param [Object] targets Targets collection (can be an ActiveRecord::Relation, Mongoid::Criteria, Array, etc.)
|
|
573
|
+
# @return [Boolean] True if targets is empty
|
|
574
|
+
def targets_empty?(targets)
|
|
575
|
+
# For ActiveRecord relations and Mongoid criteria, use exists? to avoid loading all records
|
|
576
|
+
if targets.respond_to?(:exists?)
|
|
577
|
+
!targets.exists?
|
|
578
|
+
else
|
|
579
|
+
# For arrays and other enumerables, use blank?
|
|
580
|
+
targets.blank?
|
|
581
|
+
end
|
|
582
|
+
end
|
|
583
|
+
|
|
584
|
+
# Processes targets in batches for memory efficiency with large collections
|
|
585
|
+
# @api private
|
|
586
|
+
#
|
|
587
|
+
# For ActiveRecord::Relation, uses find_each which loads records in batches (default 1000).
|
|
588
|
+
# For Mongoid::Criteria, uses each which leverages MongoDB's cursor batching.
|
|
589
|
+
# For Arrays and other enumerables, uses standard iteration.
|
|
590
|
+
#
|
|
591
|
+
# Note: When called from async jobs (notify_all_later), ActiveRecord relations may be
|
|
592
|
+
# serialized to arrays before reaching this method, which limits batch processing benefits.
|
|
593
|
+
# Consider using notify_later with target_type instead of notify_all_later with relations
|
|
594
|
+
# for large datasets in async scenarios.
|
|
595
|
+
#
|
|
596
|
+
# @param [Object] targets Targets collection (can be an ActiveRecord::Relation, Mongoid::Criteria, Array, etc.)
|
|
597
|
+
# @param [Object] notifiable Notifiable instance
|
|
598
|
+
# @param [Hash] options Options for notifications
|
|
599
|
+
# @option options [Integer] :batch_size (1000) Batch size for ActiveRecord find_each (optional)
|
|
600
|
+
# @return [Array<Notification>] Array of generated notifications
|
|
601
|
+
def process_targets_in_batches(targets, notifiable, options = {})
|
|
602
|
+
notifications = []
|
|
603
|
+
|
|
604
|
+
# For ActiveRecord relations, use find_each to process in batches
|
|
605
|
+
# This loads records in batches (default 1000) to avoid loading all records into memory
|
|
606
|
+
if targets.respond_to?(:find_each)
|
|
607
|
+
batch_options = {}
|
|
608
|
+
batch_options[:batch_size] = options[:batch_size] if options[:batch_size]
|
|
609
|
+
|
|
610
|
+
targets.find_each(**batch_options) do |target|
|
|
611
|
+
notification = notify_to(target, notifiable, options)
|
|
612
|
+
notifications << notification
|
|
613
|
+
end
|
|
614
|
+
else
|
|
615
|
+
# For arrays and other enumerables, use standard map approach
|
|
616
|
+
# Already in memory, so no batching benefit
|
|
617
|
+
notifications = targets.map { |target| notify_to(target, notifiable, options) }
|
|
618
|
+
end
|
|
619
|
+
|
|
620
|
+
notifications
|
|
621
|
+
end
|
|
549
622
|
end
|
|
550
623
|
|
|
551
624
|
# :nocov:
|
|
@@ -82,6 +82,15 @@ module ActivityNotification
|
|
|
82
82
|
# @return [String] Email address as sender of notification email.
|
|
83
83
|
attr_accessor :mailer_sender
|
|
84
84
|
|
|
85
|
+
# @overload mailer_cc
|
|
86
|
+
# Returns carbon copy (CC) email address(es) for notification email
|
|
87
|
+
# @return [String, Array<String>, Proc] CC email address(es) for notification email.
|
|
88
|
+
# @overload mailer_cc=(value)
|
|
89
|
+
# Sets carbon copy (CC) email address(es) for notification email
|
|
90
|
+
# @param [String, Array<String>, Proc] mailer_cc The new mailer_cc
|
|
91
|
+
# @return [String, Array<String>, Proc] CC email address(es) for notification email.
|
|
92
|
+
attr_accessor :mailer_cc
|
|
93
|
+
|
|
85
94
|
# @overload mailer
|
|
86
95
|
# Returns mailer class for email notification
|
|
87
96
|
# @return [String] Mailer class for email notification.
|
|
@@ -236,6 +245,7 @@ module ActivityNotification
|
|
|
236
245
|
@subscribe_to_email_as_default = nil
|
|
237
246
|
@subscribe_to_optional_targets_as_default = nil
|
|
238
247
|
@mailer_sender = nil
|
|
248
|
+
@mailer_cc = nil
|
|
239
249
|
@mailer = 'ActivityNotification::Mailer'
|
|
240
250
|
@parent_mailer = 'ActionMailer::Base'
|
|
241
251
|
@parent_job = 'ActiveJob::Base'
|
|
@@ -74,6 +74,7 @@ module ActivityNotification
|
|
|
74
74
|
subject: :subject_for,
|
|
75
75
|
from: :mailer_from,
|
|
76
76
|
reply_to: :mailer_reply_to,
|
|
77
|
+
cc: :mailer_cc,
|
|
77
78
|
message_id: nil
|
|
78
79
|
}.each do |header_name, default_method|
|
|
79
80
|
overridding_method_name = "overriding_notification_email_#{header_name.to_s}"
|
|
@@ -81,7 +82,12 @@ module ActivityNotification
|
|
|
81
82
|
@notification.notifiable.send(overridding_method_name, @target, key).present?
|
|
82
83
|
@notification.notifiable.send(overridding_method_name, @target, key)
|
|
83
84
|
elsif default_method
|
|
84
|
-
|
|
85
|
+
# Special handling for methods that take target instead of key
|
|
86
|
+
if [:mailer_cc].include?(default_method)
|
|
87
|
+
send(default_method, @target)
|
|
88
|
+
else
|
|
89
|
+
send(default_method, key)
|
|
90
|
+
end
|
|
85
91
|
else
|
|
86
92
|
nil
|
|
87
93
|
end
|
|
@@ -99,6 +105,26 @@ module ActivityNotification
|
|
|
99
105
|
target.mailer_to
|
|
100
106
|
end
|
|
101
107
|
|
|
108
|
+
# Returns carbon copy (CC) email address(es).
|
|
109
|
+
#
|
|
110
|
+
# @param [Object] target Target instance to notify
|
|
111
|
+
# @return [String, Array<String>, nil] CC email address(es) or nil
|
|
112
|
+
def mailer_cc(target)
|
|
113
|
+
if target.respond_to?(:mailer_cc)
|
|
114
|
+
target.mailer_cc
|
|
115
|
+
elsif ActivityNotification.config.mailer_cc.present?
|
|
116
|
+
if ActivityNotification.config.mailer_cc.is_a?(Proc)
|
|
117
|
+
# Get the notification key from current context
|
|
118
|
+
key = @notification ? @notification.key : nil
|
|
119
|
+
ActivityNotification.config.mailer_cc.call(key)
|
|
120
|
+
else
|
|
121
|
+
ActivityNotification.config.mailer_cc
|
|
122
|
+
end
|
|
123
|
+
else
|
|
124
|
+
nil
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
102
128
|
# Returns sender email address as 'reply_to'.
|
|
103
129
|
#
|
|
104
130
|
# @param [String] key Key of the notification or batch notification email
|
|
@@ -45,6 +45,14 @@ ActivityNotification.configure do |config|
|
|
|
45
45
|
# note that it will be overwritten if you use your own mailer class with default "from" parameter.
|
|
46
46
|
config.mailer_sender = 'please-change-me-at-config-initializers-activity_notification@example.com'
|
|
47
47
|
|
|
48
|
+
# Configure the carbon copy (CC) email address(es) for notification emails.
|
|
49
|
+
# You can set a single email address, an array of email addresses, or a Proc that returns either.
|
|
50
|
+
# Note that this can be overridden per target by defining a mailer_cc method in the target model,
|
|
51
|
+
# or per notification by defining overriding_notification_email_cc in the notifiable model.
|
|
52
|
+
# config.mailer_cc = 'admin@example.com'
|
|
53
|
+
# config.mailer_cc = ['admin@example.com', 'support@example.com']
|
|
54
|
+
# config.mailer_cc = ->(key){ key.include?('urgent') ? 'urgent@example.com' : nil }
|
|
55
|
+
|
|
48
56
|
# Configure the class responsible to send e-mails.
|
|
49
57
|
# config.mailer = "ActivityNotification::Mailer"
|
|
50
58
|
|