activity_notification 1.4.4 → 2.2.4
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 +5 -5
- data/.github/ISSUE_TEMPLATE/bug_report.md +22 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +17 -0
- data/.github/pull_request_template.md +13 -0
- data/.github/workflows/build.yml +116 -0
- data/.gitignore +15 -3
- data/CHANGELOG.md +200 -1
- data/Gemfile +17 -2
- data/Procfile +2 -0
- data/README.md +168 -1033
- data/Rakefile +19 -10
- data/activity_notification.gemspec +14 -9
- data/app/channels/activity_notification/notification_api_channel.rb +12 -0
- data/app/channels/activity_notification/notification_api_with_devise_channel.rb +46 -0
- data/app/channels/activity_notification/notification_channel.rb +37 -0
- data/app/channels/activity_notification/notification_with_devise_channel.rb +51 -0
- data/app/controllers/activity_notification/apidocs_controller.rb +75 -0
- data/app/controllers/activity_notification/notifications_api_controller.rb +143 -0
- data/app/controllers/activity_notification/notifications_api_with_devise_controller.rb +7 -0
- data/app/controllers/activity_notification/notifications_controller.rb +60 -54
- data/app/controllers/activity_notification/subscriptions_api_controller.rb +197 -0
- data/app/controllers/activity_notification/subscriptions_api_with_devise_controller.rb +7 -0
- data/app/controllers/activity_notification/subscriptions_controller.rb +83 -73
- data/app/jobs/activity_notification/notify_all_job.rb +25 -0
- data/app/jobs/activity_notification/notify_job.rb +26 -0
- data/app/jobs/activity_notification/notify_to_job.rb +25 -0
- data/app/views/activity_notification/notifications/default/_default.html.erb +23 -23
- data/app/views/activity_notification/notifications/default/_default_without_grouping.html.erb +19 -19
- data/app/views/activity_notification/notifications/default/_index.html.erb +3 -3
- data/app/views/activity_notification/notifications/default/index.html.erb +60 -7
- data/app/views/activity_notification/notifications/default/open.js.erb +2 -2
- data/app/views/activity_notification/notifications/default/open_all.js.erb +2 -2
- data/app/views/activity_notification/notifications/default/show.html.erb +2 -2
- data/app/views/activity_notification/optional_targets/default/action_cable_channel/_default.html.erb +176 -0
- data/app/views/activity_notification/optional_targets/default/base/_default.text.erb +1 -1
- data/app/views/activity_notification/optional_targets/default/slack/_default.text.erb +1 -1
- data/app/views/activity_notification/subscriptions/default/_form.html.erb +2 -2
- data/app/views/activity_notification/subscriptions/default/_notification_keys.html.erb +5 -33
- data/app/views/activity_notification/subscriptions/default/_subscription.html.erb +8 -8
- data/app/views/activity_notification/subscriptions/default/index.html.erb +13 -9
- data/app/views/activity_notification/subscriptions/default/show.html.erb +3 -3
- data/app/views/activity_notification/subscriptions/default/subscribe.js.erb +1 -1
- data/app/views/activity_notification/subscriptions/default/subscribe_to_email.js.erb +1 -1
- data/app/views/activity_notification/subscriptions/default/subscribe_to_optional_target.js.erb +1 -1
- data/app/views/activity_notification/subscriptions/default/unsubscribe.js.erb +1 -1
- data/app/views/activity_notification/subscriptions/default/unsubscribe_to_email.js.erb +1 -1
- data/app/views/activity_notification/subscriptions/default/unsubscribe_to_optional_target.js.erb +1 -1
- data/bin/_dynamodblocal +4 -0
- data/bin/bundle_update.sh +7 -0
- data/bin/deploy_on_heroku.sh +16 -0
- data/bin/install_dynamodblocal.sh +5 -0
- data/bin/start_dynamodblocal.sh +47 -0
- data/bin/stop_dynamodblocal.sh +34 -0
- data/docs/CODE_OF_CONDUCT.md +76 -0
- data/docs/CONTRIBUTING.md +36 -0
- data/docs/Functions.md +1146 -0
- data/docs/Setup.md +817 -0
- data/docs/Testing.md +148 -0
- data/gemfiles/Gemfile.rails-5.0 +8 -1
- data/gemfiles/Gemfile.rails-5.1 +7 -1
- data/gemfiles/Gemfile.rails-5.2 +24 -0
- data/gemfiles/Gemfile.rails-6.0 +23 -0
- data/gemfiles/Gemfile.rails-6.1 +22 -0
- data/gemfiles/Gemfile.rails-7.0 +25 -0
- data/lib/activity_notification/apis/notification_api.rb +356 -159
- data/lib/activity_notification/apis/subscription_api.rb +98 -59
- data/lib/activity_notification/apis/swagger.rb +6 -0
- data/lib/activity_notification/common.rb +18 -7
- data/lib/activity_notification/config.rb +176 -30
- data/lib/activity_notification/controllers/common_api_controller.rb +30 -0
- data/lib/activity_notification/controllers/common_controller.rb +47 -27
- data/lib/activity_notification/controllers/concerns/swagger/error_responses.rb +55 -0
- data/lib/activity_notification/controllers/concerns/swagger/notifications_api.rb +273 -0
- data/lib/activity_notification/controllers/concerns/swagger/notifications_parameters.rb +92 -0
- data/lib/activity_notification/controllers/concerns/swagger/subscriptions_api.rb +405 -0
- data/lib/activity_notification/controllers/concerns/swagger/subscriptions_parameters.rb +50 -0
- data/lib/activity_notification/controllers/devise_authentication_controller.rb +22 -5
- data/lib/activity_notification/gem_version.rb +14 -0
- data/lib/activity_notification/helpers/errors.rb +6 -0
- data/lib/activity_notification/helpers/view_helpers.rb +118 -28
- data/lib/activity_notification/mailers/helpers.rb +19 -12
- data/lib/activity_notification/models/concerns/notifiable.rb +142 -55
- data/lib/activity_notification/models/concerns/subscriber.rb +28 -13
- data/lib/activity_notification/models/concerns/swagger/error_schema.rb +36 -0
- data/lib/activity_notification/models/concerns/swagger/notification_schema.rb +209 -0
- data/lib/activity_notification/models/concerns/swagger/subscription_schema.rb +162 -0
- data/lib/activity_notification/models/concerns/target.rb +131 -32
- data/lib/activity_notification/models/notification.rb +1 -0
- data/lib/activity_notification/models/subscription.rb +1 -0
- data/lib/activity_notification/models.rb +23 -1
- data/lib/activity_notification/optional_targets/action_cable_api_channel.rb +69 -0
- data/lib/activity_notification/optional_targets/action_cable_channel.rb +68 -0
- data/lib/activity_notification/optional_targets/base.rb +9 -15
- data/lib/activity_notification/orm/active_record/notification.rb +23 -34
- data/lib/activity_notification/orm/active_record/subscription.rb +1 -1
- data/lib/activity_notification/orm/active_record.rb +1 -1
- data/lib/activity_notification/orm/dynamoid/extension.rb +262 -0
- data/lib/activity_notification/orm/dynamoid/notification.rb +224 -0
- data/lib/activity_notification/orm/dynamoid/subscription.rb +82 -0
- data/lib/activity_notification/orm/dynamoid.rb +530 -0
- data/lib/activity_notification/orm/mongoid/notification.rb +29 -28
- data/lib/activity_notification/orm/mongoid/subscription.rb +3 -3
- data/lib/activity_notification/orm/mongoid.rb +33 -1
- data/lib/activity_notification/rails/routes.rb +273 -60
- data/lib/activity_notification/renderable.rb +22 -7
- data/lib/activity_notification/roles/acts_as_notifiable.rb +64 -1
- data/lib/activity_notification/roles/acts_as_target.rb +99 -9
- data/lib/activity_notification/version.rb +1 -1
- data/lib/activity_notification.rb +14 -0
- data/lib/generators/activity_notification/controllers_generator.rb +2 -1
- data/lib/generators/templates/activity_notification.rb +61 -7
- data/lib/generators/templates/controllers/README +2 -2
- data/lib/generators/templates/controllers/notifications_api_controller.rb +31 -0
- data/lib/generators/templates/controllers/notifications_api_with_devise_controller.rb +31 -0
- data/lib/generators/templates/controllers/notifications_controller.rb +1 -37
- data/lib/generators/templates/controllers/notifications_with_devise_controller.rb +1 -45
- data/lib/generators/templates/controllers/subscriptions_api_controller.rb +61 -0
- data/lib/generators/templates/controllers/subscriptions_api_with_devise_controller.rb +61 -0
- data/lib/generators/templates/controllers/subscriptions_controller.rb +14 -37
- data/lib/generators/templates/controllers/subscriptions_with_devise_controller.rb +14 -45
- data/lib/generators/templates/migrations/migration.rb +5 -5
- data/lib/generators/templates/models/README +8 -4
- data/lib/generators/templates/models/notification.rb +1 -1
- data/lib/generators/templates/models/subscription.rb +1 -1
- data/lib/tasks/activity_notification_tasks.rake +14 -4
- data/package.json +8 -0
- data/spec/channels/notification_api_channel_shared_examples.rb +59 -0
- data/spec/channels/notification_api_channel_spec.rb +49 -0
- data/spec/channels/notification_api_with_devise_channel_spec.rb +76 -0
- data/spec/channels/notification_channel_shared_examples.rb +59 -0
- data/spec/channels/notification_channel_spec.rb +48 -0
- data/spec/channels/notification_with_devise_channel_spec.rb +97 -0
- data/spec/concerns/apis/notification_api_spec.rb +177 -12
- data/spec/concerns/apis/subscription_api_spec.rb +146 -4
- data/spec/concerns/common_spec.rb +25 -3
- data/spec/concerns/models/notifiable_spec.rb +161 -11
- data/spec/concerns/models/subscriber_spec.rb +253 -79
- data/spec/concerns/models/target_spec.rb +180 -47
- data/spec/concerns/renderable_spec.rb +35 -16
- data/spec/config_spec.rb +52 -1
- data/spec/controllers/controller_spec_utility.rb +100 -0
- data/spec/controllers/notifications_api_controller_shared_examples.rb +506 -0
- data/spec/controllers/notifications_api_controller_spec.rb +19 -0
- data/spec/controllers/notifications_api_with_devise_controller_spec.rb +60 -0
- data/spec/controllers/notifications_controller_shared_examples.rb +55 -76
- data/spec/controllers/notifications_controller_spec.rb +1 -2
- data/spec/controllers/notifications_with_devise_controller_spec.rb +14 -8
- data/spec/controllers/subscriptions_api_controller_shared_examples.rb +750 -0
- data/spec/controllers/subscriptions_api_controller_spec.rb +19 -0
- data/spec/controllers/subscriptions_api_with_devise_controller_spec.rb +60 -0
- data/spec/controllers/subscriptions_controller_shared_examples.rb +99 -121
- data/spec/controllers/subscriptions_controller_spec.rb +1 -2
- data/spec/controllers/subscriptions_with_devise_controller_spec.rb +14 -8
- data/spec/factories/notifications.rb +1 -1
- data/spec/factories/subscriptions.rb +3 -3
- data/spec/factories/users.rb +3 -3
- data/spec/generators/migration/migration_generator_spec.rb +29 -4
- data/spec/helpers/view_helpers_spec.rb +31 -21
- data/spec/jobs/notify_all_job_spec.rb +23 -0
- data/spec/jobs/notify_job_spec.rb +23 -0
- data/spec/jobs/notify_to_job_spec.rb +23 -0
- data/spec/mailers/mailer_spec.rb +42 -1
- data/spec/models/dummy/dummy_group_spec.rb +4 -0
- data/spec/models/dummy/dummy_notifiable_spec.rb +4 -0
- data/spec/models/dummy/dummy_notifier_spec.rb +4 -0
- data/spec/models/dummy/dummy_subscriber_spec.rb +3 -0
- data/spec/models/dummy/dummy_target_spec.rb +4 -0
- data/spec/models/notification_spec.rb +181 -45
- data/spec/models/subscription_spec.rb +77 -27
- data/spec/optional_targets/action_cable_api_channel_spec.rb +34 -0
- data/spec/optional_targets/action_cable_channel_spec.rb +41 -0
- data/spec/optional_targets/amazon_sns_spec.rb +0 -2
- data/spec/optional_targets/slack_spec.rb +0 -2
- data/spec/orm/dynamoid_spec.rb +115 -0
- data/spec/rails_app/Rakefile +9 -0
- data/spec/rails_app/app/assets/config/manifest.js +3 -0
- data/spec/rails_app/app/assets/javascripts/application.js +2 -1
- data/spec/rails_app/app/assets/javascripts/cable.js +12 -0
- data/spec/rails_app/app/controllers/admins_controller.rb +21 -0
- data/spec/rails_app/app/controllers/application_controller.rb +1 -1
- data/spec/rails_app/app/controllers/articles_controller.rb +6 -1
- data/spec/rails_app/app/controllers/comments_controller.rb +3 -1
- data/spec/rails_app/app/controllers/spa_controller.rb +7 -0
- data/spec/rails_app/app/controllers/users/notifications_controller.rb +0 -65
- data/spec/rails_app/app/controllers/users/notifications_with_devise_controller.rb +0 -73
- data/spec/rails_app/app/controllers/users/subscriptions_controller.rb +0 -77
- data/spec/rails_app/app/controllers/users/subscriptions_with_devise_controller.rb +0 -85
- data/spec/rails_app/app/controllers/users_controller.rb +26 -0
- data/spec/rails_app/app/javascript/App.vue +40 -0
- data/spec/rails_app/app/javascript/components/DeviseTokenAuth.vue +82 -0
- data/spec/rails_app/app/javascript/components/Top.vue +98 -0
- data/spec/rails_app/app/javascript/components/notifications/Index.vue +200 -0
- data/spec/rails_app/app/javascript/components/notifications/Notification.vue +133 -0
- data/spec/rails_app/app/javascript/components/notifications/NotificationContent.vue +122 -0
- data/spec/rails_app/app/javascript/components/subscriptions/Index.vue +279 -0
- data/spec/rails_app/app/javascript/components/subscriptions/NewSubscription.vue +112 -0
- data/spec/rails_app/app/javascript/components/subscriptions/NotificationKey.vue +141 -0
- data/spec/rails_app/app/javascript/components/subscriptions/Subscription.vue +226 -0
- data/spec/rails_app/app/javascript/config/development.js +5 -0
- data/spec/rails_app/app/javascript/config/environment.js +7 -0
- data/spec/rails_app/app/javascript/config/production.js +5 -0
- data/spec/rails_app/app/javascript/config/test.js +5 -0
- data/spec/rails_app/app/javascript/packs/application.js +18 -0
- data/spec/rails_app/app/javascript/packs/spa.js +14 -0
- data/spec/rails_app/app/javascript/router/index.js +73 -0
- data/spec/rails_app/app/javascript/store/index.js +37 -0
- data/spec/rails_app/app/models/admin.rb +15 -10
- data/spec/rails_app/app/models/article.rb +25 -20
- data/spec/rails_app/app/models/comment.rb +27 -62
- data/spec/rails_app/app/models/dummy/dummy_base.rb +1 -0
- data/spec/rails_app/app/models/dummy/dummy_group.rb +9 -0
- data/spec/rails_app/app/models/dummy/dummy_notifiable.rb +1 -0
- data/spec/rails_app/app/models/dummy/dummy_notifiable_target.rb +27 -0
- data/spec/rails_app/app/models/dummy/dummy_notifier.rb +1 -0
- data/spec/rails_app/app/models/dummy/dummy_subscriber.rb +1 -0
- data/spec/rails_app/app/models/dummy/dummy_target.rb +1 -0
- data/spec/rails_app/app/models/user.rb +44 -18
- data/spec/rails_app/app/views/activity_notification/notifications/default/article/_update.html.erb +146 -0
- data/spec/rails_app/app/views/activity_notification/notifications/users/overridden/custom/_test.html.erb +1 -0
- data/spec/rails_app/app/views/activity_notification/optional_targets/admins/amazon_sns/comment/_default.text.erb +1 -1
- data/spec/rails_app/app/views/articles/index.html.erb +68 -20
- data/spec/rails_app/app/views/articles/show.html.erb +1 -1
- data/spec/rails_app/app/views/layouts/_header.html.erb +9 -3
- data/spec/rails_app/app/views/spa/index.html.erb +2 -0
- data/spec/rails_app/babel.config.js +72 -0
- data/spec/rails_app/bin/webpack +18 -0
- data/spec/rails_app/bin/webpack-dev-server +18 -0
- data/spec/rails_app/config/application.rb +26 -6
- data/spec/rails_app/config/cable.yml +8 -0
- data/spec/rails_app/config/database.yml +1 -1
- data/spec/rails_app/config/dynamoid.rb +13 -0
- data/spec/rails_app/config/environment.rb +5 -1
- data/spec/rails_app/config/environments/development.rb +5 -0
- data/spec/rails_app/config/environments/production.rb +7 -1
- data/spec/rails_app/config/environments/test.rb +7 -11
- data/spec/rails_app/config/initializers/activity_notification.rb +63 -9
- data/spec/rails_app/config/initializers/copy_it.aws.rb.template +6 -0
- data/spec/rails_app/config/initializers/devise_token_auth.rb +55 -0
- data/spec/rails_app/config/initializers/mysql.rb +9 -0
- data/spec/rails_app/config/locales/activity_notification.en.yml +10 -4
- data/spec/rails_app/config/routes.rb +42 -1
- data/spec/rails_app/config/webpack/development.js +5 -0
- data/spec/rails_app/config/webpack/environment.js +7 -0
- data/spec/rails_app/config/webpack/loaders/vue.js +6 -0
- data/spec/rails_app/config/webpack/production.js +5 -0
- data/spec/rails_app/config/webpack/test.js +5 -0
- data/spec/rails_app/config/webpacker.yml +97 -0
- data/spec/rails_app/db/migrate/{20160715050433_create_test_tables.rb → 20160716000000_create_test_tables.rb} +1 -1
- data/spec/rails_app/db/migrate/{20160715050420_create_activity_notification_tables.rb → 20181209000000_create_activity_notification_tables.rb} +3 -3
- data/spec/rails_app/db/migrate/20191201000000_add_tokens_to_users.rb +10 -0
- data/spec/rails_app/db/schema.rb +46 -43
- data/spec/rails_app/db/seeds.rb +28 -4
- data/spec/rails_app/lib/custom_optional_targets/raise_error.rb +14 -0
- data/spec/rails_app/lib/mailer_previews/mailer_preview.rb +14 -4
- data/spec/rails_app/package.json +23 -0
- data/spec/rails_app/postcss.config.js +12 -0
- data/spec/roles/acts_as_group_spec.rb +0 -2
- data/spec/roles/acts_as_notifiable_spec.rb +80 -20
- data/spec/roles/acts_as_notifier_spec.rb +0 -2
- data/spec/roles/acts_as_target_spec.rb +1 -5
- data/spec/spec_helper.rb +13 -11
- data/spec/version_spec.rb +31 -0
- metadata +306 -53
- data/.travis.yml +0 -85
- data/Gemfile.lock +0 -234
- data/gemfiles/Gemfile.rails-4.2 +0 -17
- data/gemfiles/Gemfile.rails-4.2.lock +0 -225
- data/gemfiles/Gemfile.rails-5.0.lock +0 -234
- data/gemfiles/Gemfile.rails-5.1.lock +0 -234
- data/spec/rails_app/app/views/activity_notification/notifications/users/overriden/custom/_test.html.erb +0 -1
- /data/spec/rails_app/app/{models → assets/images}/.keep +0 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
require 'dynamoid'
|
|
2
|
+
require 'activity_notification/apis/subscription_api'
|
|
3
|
+
|
|
4
|
+
module ActivityNotification
|
|
5
|
+
module ORM
|
|
6
|
+
module Dynamoid
|
|
7
|
+
# Subscription model implementation generated by ActivityNotification.
|
|
8
|
+
class Subscription
|
|
9
|
+
include ::Dynamoid::Document
|
|
10
|
+
include ActiveModel::AttributeAssignment
|
|
11
|
+
include DynamoidExtension
|
|
12
|
+
include Association
|
|
13
|
+
include SubscriptionApi
|
|
14
|
+
|
|
15
|
+
table name: ActivityNotification.config.subscription_table_name, key: :id
|
|
16
|
+
|
|
17
|
+
# Belongs to target instance of this subscription as polymorphic association using composite key.
|
|
18
|
+
# @scope instance
|
|
19
|
+
# @return [Object] Target instance of this subscription
|
|
20
|
+
belongs_to_composite_xdb_record :target
|
|
21
|
+
|
|
22
|
+
field :key, :string
|
|
23
|
+
field :subscribing, :boolean, default: ActivityNotification.config.subscribe_as_default
|
|
24
|
+
field :subscribing_to_email, :boolean, default: ActivityNotification.config.subscribe_to_email_as_default
|
|
25
|
+
field :subscribed_at, :datetime
|
|
26
|
+
field :unsubscribed_at, :datetime
|
|
27
|
+
field :subscribed_to_email_at, :datetime
|
|
28
|
+
field :unsubscribed_to_email_at, :datetime
|
|
29
|
+
field :optional_targets, :raw, default: {}
|
|
30
|
+
|
|
31
|
+
global_secondary_index name: :index_target_key_created_at, hash_key: :target_key, range_key: :created_at, projected_attributes: :all
|
|
32
|
+
|
|
33
|
+
validates :target, presence: true
|
|
34
|
+
validates :key, presence: true, uniqueness: { scope: :target_key }
|
|
35
|
+
validates_inclusion_of :subscribing, in: [true, false]
|
|
36
|
+
validates_inclusion_of :subscribing_to_email, in: [true, false]
|
|
37
|
+
validate :subscribing_to_email_cannot_be_true_when_subscribing_is_false
|
|
38
|
+
validates :subscribed_at, presence: true, if: :subscribing
|
|
39
|
+
validates :unsubscribed_at, presence: true, unless: :subscribing
|
|
40
|
+
validates :subscribed_to_email_at, presence: true, if: :subscribing_to_email
|
|
41
|
+
validates :unsubscribed_to_email_at, presence: true, unless: :subscribing_to_email
|
|
42
|
+
validate :subscribing_to_optional_target_cannot_be_true_when_subscribing_is_false
|
|
43
|
+
|
|
44
|
+
%i[ filtered_by_association filtered_by_target
|
|
45
|
+
filtered_by_target_type filtered_by_key filtered_by_options
|
|
46
|
+
latest_order earliest_order latest_order! earliest_order!
|
|
47
|
+
latest_subscribed_order earliest_subscribed_order key_order
|
|
48
|
+
reload
|
|
49
|
+
uniq_keys
|
|
50
|
+
].each do |method|
|
|
51
|
+
# Return a criteria chain in response to a method that will begin or end a chain.
|
|
52
|
+
# For more information, see Dynamoid::Criteria::Chain.
|
|
53
|
+
singleton_class.send(:define_method, method) do |*args, &block|
|
|
54
|
+
# Use scan_index_forward with true as default value to convert Dynamoid::Document into Dynamoid::Criteria::Chain
|
|
55
|
+
# https://github.com/Dynamoid/dynamoid/blob/master/lib/dynamoid/document.rb
|
|
56
|
+
# https://github.com/Dynamoid/dynamoid/blob/master/lib/dynamoid/components.rb
|
|
57
|
+
# https://github.com/Dynamoid/dynamoid/blob/master/lib/dynamoid/criteria.rb
|
|
58
|
+
# https://github.com/Dynamoid/dynamoid/blob/master/lib/dynamoid/criteria/chain.rb
|
|
59
|
+
scan_index_forward(true).send(method, *args, &block)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
%i[ with_target ].each do |method|
|
|
64
|
+
singleton_class.send(:define_method, method) do |*args, &block|
|
|
65
|
+
self
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Initialize without options to use Dynamoid.config.store_datetime_as_string
|
|
70
|
+
# https://github.com/Dynamoid/dynamoid/blob/master/lib/dynamoid/dumping.rb
|
|
71
|
+
@@date_time_dumper = ::Dynamoid::Dumping::DateTimeDumper.new({})
|
|
72
|
+
|
|
73
|
+
# Convert Time value to store in database as Hash value.
|
|
74
|
+
# @param [Time] time Time value to store in database as Hash value
|
|
75
|
+
# @return [Integer, String] Converted Time value
|
|
76
|
+
def self.convert_time_as_hash(time)
|
|
77
|
+
@@date_time_dumper.process(time)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,530 @@
|
|
|
1
|
+
require 'dynamoid/adapter_plugin/aws_sdk_v3'
|
|
2
|
+
require_relative 'dynamoid/extension.rb'
|
|
3
|
+
|
|
4
|
+
module ActivityNotification
|
|
5
|
+
module Association
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
included do
|
|
9
|
+
class_attribute :_associated_composite_records
|
|
10
|
+
self._associated_composite_records = []
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class_methods do
|
|
14
|
+
# Defines has_many association with ActivityNotification models.
|
|
15
|
+
# @return [Dynamoid::Criteria::Chain] Database query of associated model instances
|
|
16
|
+
def has_many_records(name, options = {})
|
|
17
|
+
has_many_composite_xdb_records name, options
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Defines polymorphic belongs_to association using composite key with models in other database.
|
|
21
|
+
def belongs_to_composite_xdb_record(name, _options = {})
|
|
22
|
+
association_name = name.to_s.singularize.underscore
|
|
23
|
+
composite_field = "#{association_name}_key".to_sym
|
|
24
|
+
field composite_field, :string
|
|
25
|
+
associated_record_field = "stored_#{association_name}".to_sym
|
|
26
|
+
field associated_record_field, :raw if ActivityNotification.config.store_with_associated_records && _options[:store_with_associated_records]
|
|
27
|
+
|
|
28
|
+
self.instance_eval do
|
|
29
|
+
define_method(name) do |reload = false|
|
|
30
|
+
reload and self.instance_variable_set("@#{name}", nil)
|
|
31
|
+
if self.instance_variable_get("@#{name}").blank?
|
|
32
|
+
composite_key = self.send(composite_field)
|
|
33
|
+
if composite_key.present? && (class_name = composite_key.split(ActivityNotification.config.composite_key_delimiter).first).present?
|
|
34
|
+
object_class = class_name.classify.constantize
|
|
35
|
+
self.instance_variable_set("@#{name}", object_class.where(id: composite_key.split(ActivityNotification.config.composite_key_delimiter).last).first)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
self.instance_variable_get("@#{name}")
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
define_method("#{name}=") do |new_instance|
|
|
42
|
+
if new_instance.nil?
|
|
43
|
+
self.send("#{composite_field}=", nil)
|
|
44
|
+
else
|
|
45
|
+
self.send("#{composite_field}=", "#{new_instance.class.name}#{ActivityNotification.config.composite_key_delimiter}#{new_instance.id}")
|
|
46
|
+
associated_record_json = new_instance.as_json(_options[:as_json_options] || {})
|
|
47
|
+
# Cast Time and DateTime field to String to handle Dynamoid unsupported type error
|
|
48
|
+
if associated_record_json.present?
|
|
49
|
+
associated_record_json.each do |k, v|
|
|
50
|
+
associated_record_json[k] = v.to_s if v.is_a?(Time) || v.is_a?(DateTime)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
self.send("#{associated_record_field}=", associated_record_json) if ActivityNotification.config.store_with_associated_records && _options[:store_with_associated_records]
|
|
54
|
+
end
|
|
55
|
+
self.instance_variable_set("@#{name}", nil)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
define_method("#{association_name}_type") do
|
|
59
|
+
composite_key = self.send(composite_field)
|
|
60
|
+
composite_key.present? ? composite_key.split(ActivityNotification.config.composite_key_delimiter).first : nil
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
define_method("#{association_name}_id") do
|
|
64
|
+
composite_key = self.send(composite_field)
|
|
65
|
+
composite_key.present? ? composite_key.split(ActivityNotification.config.composite_key_delimiter).last : nil
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
self._associated_composite_records.push(association_name.to_sym)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Defines polymorphic has_many association using composite key with models in other database.
|
|
73
|
+
# @todo Add dependent option
|
|
74
|
+
def has_many_composite_xdb_records(name, options = {})
|
|
75
|
+
association_name = options[:as] || name.to_s.underscore
|
|
76
|
+
composite_field = "#{association_name}_key".to_sym
|
|
77
|
+
object_name = options[:class_name] || name.to_s.singularize.camelize
|
|
78
|
+
object_class = object_name.classify.constantize
|
|
79
|
+
|
|
80
|
+
self.instance_eval do
|
|
81
|
+
# Set default reload arg to true since Dynamoid::Criteria::Chain is stateful on the query
|
|
82
|
+
define_method(name) do |reload = true|
|
|
83
|
+
reload and self.instance_variable_set("@#{name}", nil)
|
|
84
|
+
if self.instance_variable_get("@#{name}").blank?
|
|
85
|
+
new_value = object_class.where(composite_field => "#{self.class.name}#{ActivityNotification.config.composite_key_delimiter}#{self.id}")
|
|
86
|
+
self.instance_variable_set("@#{name}", new_value)
|
|
87
|
+
end
|
|
88
|
+
self.instance_variable_get("@#{name}")
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Defines update method as update_attributes method
|
|
95
|
+
def update(attributes)
|
|
96
|
+
attributes_with_association = attributes.map { |attribute, value|
|
|
97
|
+
self.class._associated_composite_records.include?(attribute) ?
|
|
98
|
+
["#{attribute}_key".to_sym, value.nil? ? nil : "#{value.class.name}#{ActivityNotification.config.composite_key_delimiter}#{value.id}"] :
|
|
99
|
+
[attribute, value]
|
|
100
|
+
}.to_h
|
|
101
|
+
update_attributes(attributes_with_association)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Monkey patching for Rails 6.0+
|
|
107
|
+
class ActiveModel::NullMutationTracker
|
|
108
|
+
# Monkey patching for Rails 6.0+
|
|
109
|
+
def force_change(attr_name); end if Rails::VERSION::MAJOR >= 6
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Entend Dynamoid to support ActivityNotification scope in Dynamoid::Criteria::Chain
|
|
113
|
+
# @private
|
|
114
|
+
module Dynamoid # :nodoc: all
|
|
115
|
+
# https://github.com/Dynamoid/dynamoid/blob/master/lib/dynamoid/criteria.rb
|
|
116
|
+
# @private
|
|
117
|
+
module Criteria
|
|
118
|
+
# https://github.com/Dynamoid/dynamoid/blob/master/lib/dynamoid/criteria/chain.rb
|
|
119
|
+
# @private
|
|
120
|
+
class Chain
|
|
121
|
+
# Selects all notification index.
|
|
122
|
+
# ActivityNotification::Notification.all_index!
|
|
123
|
+
# is defined same as
|
|
124
|
+
# ActivityNotification::Notification.group_owners_only.latest_order
|
|
125
|
+
# @scope class
|
|
126
|
+
# @example Get all notification index of the @user
|
|
127
|
+
# @notifications = @user.notifications.all_index!
|
|
128
|
+
# @notifications = @user.notifications.group_owners_only.latest_order
|
|
129
|
+
# @param [Boolean] reverse If notification index will be ordered as earliest first
|
|
130
|
+
# @param [Boolean] with_group_members If notification index will include group members
|
|
131
|
+
# @return [Dynamoid::Criteria::Chain] Database query of filtered notifications
|
|
132
|
+
def all_index!(reverse = false, with_group_members = false)
|
|
133
|
+
target_index = with_group_members ? self : group_owners_only
|
|
134
|
+
reverse ? target_index.earliest_order : target_index.latest_order
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Selects unopened notification index.
|
|
138
|
+
# ActivityNotification::Notification.unopened_index
|
|
139
|
+
# is defined same as
|
|
140
|
+
# ActivityNotification::Notification.unopened_only.group_owners_only.latest_order
|
|
141
|
+
# @scope class
|
|
142
|
+
# @example Get unopened notificaton index of the @user
|
|
143
|
+
# @notifications = @user.notifications.unopened_index
|
|
144
|
+
# @notifications = @user.notifications.unopened_only.group_owners_only.latest_order
|
|
145
|
+
# @param [Boolean] reverse If notification index will be ordered as earliest first
|
|
146
|
+
# @param [Boolean] with_group_members If notification index will include group members
|
|
147
|
+
# @return [Dynamoid::Criteria::Chain] Database query of filtered notifications
|
|
148
|
+
def unopened_index(reverse = false, with_group_members = false)
|
|
149
|
+
target_index = with_group_members ? unopened_only : unopened_only.group_owners_only
|
|
150
|
+
reverse ? target_index.earliest_order : target_index.latest_order
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Selects unopened notification index.
|
|
154
|
+
# ActivityNotification::Notification.opened_index(limit)
|
|
155
|
+
# is defined same as
|
|
156
|
+
# ActivityNotification::Notification.opened_only(limit).group_owners_only.latest_order
|
|
157
|
+
# @scope class
|
|
158
|
+
# @example Get unopened notificaton index of the @user with limit 10
|
|
159
|
+
# @notifications = @user.notifications.opened_index(10)
|
|
160
|
+
# @notifications = @user.notifications.opened_only(10).group_owners_only.latest_order
|
|
161
|
+
# @param [Integer] limit Limit to query for opened notifications
|
|
162
|
+
# @param [Boolean] reverse If notification index will be ordered as earliest first
|
|
163
|
+
# @param [Boolean] with_group_members If notification index will include group members
|
|
164
|
+
# @return [Dynamoid::Criteria::Chain] Database query of filtered notifications
|
|
165
|
+
def opened_index(limit, reverse = false, with_group_members = false)
|
|
166
|
+
target_index = with_group_members ? opened_only(limit) : opened_only(limit).group_owners_only
|
|
167
|
+
reverse ? target_index.earliest_order : target_index.latest_order
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Selects filtered notifications or subscriptions by associated instance.
|
|
171
|
+
# @scope class
|
|
172
|
+
# @param [String] name Association name
|
|
173
|
+
# @param [Object] instance Associated instance
|
|
174
|
+
# @return [Dynamoid::Criteria::Chain] Database query of filtered notifications or subscriptions
|
|
175
|
+
def filtered_by_association(name, instance)
|
|
176
|
+
instance.present? ? where("#{name}_key" => "#{instance.class.name}#{ActivityNotification.config.composite_key_delimiter}#{instance.id}") : where("#{name}_key.null" => true)
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# Selects filtered notifications or subscriptions by association type.
|
|
180
|
+
# @scope class
|
|
181
|
+
# @param [String] name Association name
|
|
182
|
+
# @param [Object] type Association type
|
|
183
|
+
# @return [Dynamoid::Criteria::Chain] Database query of filtered notifications or subscriptions
|
|
184
|
+
def filtered_by_association_type(name, type)
|
|
185
|
+
type.present? ? where("#{name}_key.begins_with" => "#{type}#{ActivityNotification.config.composite_key_delimiter}") : none
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# Selects filtered notifications or subscriptions by association type and id.
|
|
189
|
+
# @scope class
|
|
190
|
+
# @param [String] name Association name
|
|
191
|
+
# @param [Object] type Association type
|
|
192
|
+
# @param [String] id Association id
|
|
193
|
+
# @return [Dynamoid::Criteria::Chain] Database query of filtered notifications or subscriptions
|
|
194
|
+
def filtered_by_association_type_and_id(name, type, id)
|
|
195
|
+
type.present? && id.present? ? where("#{name}_key" => "#{type}#{ActivityNotification.config.composite_key_delimiter}#{id}") : none
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# Selects filtered notifications or subscriptions by target instance.
|
|
199
|
+
# ActivityNotification::Notification.filtered_by_target(@user)
|
|
200
|
+
# is the same as
|
|
201
|
+
# @user.notifications
|
|
202
|
+
# @scope class
|
|
203
|
+
# @param [Object] target Target instance for filter
|
|
204
|
+
# @return [Dynamoid::Criteria::Chain] Database query of filtered notifications or subscriptions
|
|
205
|
+
def filtered_by_target(target)
|
|
206
|
+
filtered_by_association("target", target)
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# Selects filtered notifications by notifiable instance.
|
|
210
|
+
# @example Get filtered unopened notificatons of the @user for @comment as notifiable
|
|
211
|
+
# @notifications = @user.notifications.unopened_only.filtered_by_instance(@comment)
|
|
212
|
+
# @scope class
|
|
213
|
+
# @param [Object] notifiable Notifiable instance for filter
|
|
214
|
+
# @return [Dynamoid::Criteria::Chain] Database query of filtered notifications
|
|
215
|
+
def filtered_by_instance(notifiable)
|
|
216
|
+
filtered_by_association("notifiable", notifiable)
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
# Selects filtered notifications by group instance.
|
|
220
|
+
# @example Get filtered unopened notificatons of the @user for @article as group
|
|
221
|
+
# @notifications = @user.notifications.unopened_only.filtered_by_group(@article)
|
|
222
|
+
# @scope class
|
|
223
|
+
# @param [Object] group Group instance for filter
|
|
224
|
+
# @return [Dynamoid::Criteria::Chain] Database query of filtered notifications
|
|
225
|
+
def filtered_by_group(group)
|
|
226
|
+
filtered_by_association("group", group)
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# Selects filtered notifications or subscriptions by target_type.
|
|
230
|
+
# @example Get filtered unopened notificatons of User as target type
|
|
231
|
+
# @notifications = ActivityNotification.Notification.unopened_only.filtered_by_target_type('User')
|
|
232
|
+
# @scope class
|
|
233
|
+
# @param [String] target_type Target type for filter
|
|
234
|
+
# @return [Dynamoid::Criteria::Chain] Database query of filtered notifications or subscriptions
|
|
235
|
+
def filtered_by_target_type(target_type)
|
|
236
|
+
filtered_by_association_type("target", target_type)
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# Selects filtered notifications by notifiable_type.
|
|
240
|
+
# @example Get filtered unopened notificatons of the @user for Comment notifiable class
|
|
241
|
+
# @notifications = @user.notifications.unopened_only.filtered_by_type('Comment')
|
|
242
|
+
# @scope class
|
|
243
|
+
# @param [String] notifiable_type Notifiable type for filter
|
|
244
|
+
# @return [Dynamoid::Criteria::Chain] Database query of filtered notifications
|
|
245
|
+
def filtered_by_type(notifiable_type)
|
|
246
|
+
filtered_by_association_type("notifiable", notifiable_type)
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
# Selects filtered notifications or subscriptions by key.
|
|
250
|
+
# @example Get filtered unopened notificatons of the @user with key 'comment.reply'
|
|
251
|
+
# @notifications = @user.notifications.unopened_only.filtered_by_key('comment.reply')
|
|
252
|
+
# @scope class
|
|
253
|
+
# @param [String] key Key of the notification for filter
|
|
254
|
+
# @return [Dynamoid::Criteria::Chain] Database query of filtered notifications or subscriptions
|
|
255
|
+
def filtered_by_key(key)
|
|
256
|
+
where(key: key)
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
# Selects filtered notifications later than specified time.
|
|
260
|
+
# @example Get filtered unopened notificatons of the @user later than @notification
|
|
261
|
+
# @notifications = @user.notifications.unopened_only.later_than(@notification.created_at)
|
|
262
|
+
# @scope class
|
|
263
|
+
# @param [Time] Created time of the notifications for filter
|
|
264
|
+
# @return [ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>] Database query of filtered notifications
|
|
265
|
+
def later_than(created_time)
|
|
266
|
+
where('created_at.gt': created_time)
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
# Selects filtered notifications earlier than specified time.
|
|
270
|
+
# @example Get filtered unopened notificatons of the @user earlier than @notification
|
|
271
|
+
# @notifications = @user.notifications.unopened_only.earlier_than(@notification.created_at)
|
|
272
|
+
# @scope class
|
|
273
|
+
# @param [Time] Created time of the notifications for filter
|
|
274
|
+
# @return [ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>] Database query of filtered notifications
|
|
275
|
+
def earlier_than(created_time)
|
|
276
|
+
where('created_at.lt': created_time)
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
# Selects filtered notifications or subscriptions by notifiable_type, group or key with filter options.
|
|
280
|
+
# @example Get filtered unopened notificatons of the @user for Comment notifiable class
|
|
281
|
+
# @notifications = @user.notifications.unopened_only.filtered_by_options({ filtered_by_type: 'Comment' })
|
|
282
|
+
# @example Get filtered unopened notificatons of the @user for @article as group
|
|
283
|
+
# @notifications = @user.notifications.unopened_only.filtered_by_options({ filtered_by_group: @article })
|
|
284
|
+
# @example Get filtered unopened notificatons of the @user for Article instance id=1 as group
|
|
285
|
+
# @notifications = @user.notifications.unopened_only.filtered_by_options({ filtered_by_group_type: 'Article', filtered_by_group_id: '1' })
|
|
286
|
+
# @example Get filtered unopened notificatons of the @user with key 'comment.reply'
|
|
287
|
+
# @notifications = @user.notifications.unopened_only.filtered_by_options({ filtered_by_key: 'comment.reply' })
|
|
288
|
+
# @example Get filtered unopened notificatons of the @user for Comment notifiable class with key 'comment.reply'
|
|
289
|
+
# @notifications = @user.notifications.unopened_only.filtered_by_options({ filtered_by_type: 'Comment', filtered_by_key: 'comment.reply' })
|
|
290
|
+
# @example Get custom filtered notificatons of the @user
|
|
291
|
+
# @notifications = @user.notifications.unopened_only.filtered_by_options({ custom_filter: ["created_at >= ?", time.hour.ago] })
|
|
292
|
+
# @scope class
|
|
293
|
+
# @param [Hash] options Options for filter
|
|
294
|
+
# @option options [String] :filtered_by_type (nil) Notifiable type for filter
|
|
295
|
+
# @option options [Object] :filtered_by_group (nil) Group instance for filter
|
|
296
|
+
# @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
|
|
297
|
+
# @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
|
|
298
|
+
# @option options [String] :filtered_by_key (nil) Key of the notification for filter
|
|
299
|
+
# @option options [String] :later_than (nil) ISO 8601 format time to filter notification index later than specified time
|
|
300
|
+
# @option options [String] :earlier_than (nil) ISO 8601 format time to filter notification index earlier than specified time
|
|
301
|
+
# @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ['created_at.gt': time.hour.ago])
|
|
302
|
+
# @return [Dynamoid::Criteria::Chain] Database query of filtered notifications or subscriptions
|
|
303
|
+
def filtered_by_options(options = {})
|
|
304
|
+
options = ActivityNotification.cast_to_indifferent_hash(options)
|
|
305
|
+
filtered_notifications = self
|
|
306
|
+
if options.has_key?(:filtered_by_type)
|
|
307
|
+
filtered_notifications = filtered_notifications.filtered_by_type(options[:filtered_by_type])
|
|
308
|
+
end
|
|
309
|
+
if options.has_key?(:filtered_by_group)
|
|
310
|
+
filtered_notifications = filtered_notifications.filtered_by_group(options[:filtered_by_group])
|
|
311
|
+
end
|
|
312
|
+
if options.has_key?(:filtered_by_group_type) && options.has_key?(:filtered_by_group_id)
|
|
313
|
+
filtered_notifications = filtered_notifications.filtered_by_association_type_and_id("group", options[:filtered_by_group_type], options[:filtered_by_group_id])
|
|
314
|
+
end
|
|
315
|
+
if options.has_key?(:filtered_by_key)
|
|
316
|
+
filtered_notifications = filtered_notifications.filtered_by_key(options[:filtered_by_key])
|
|
317
|
+
end
|
|
318
|
+
if options.has_key?(:later_than)
|
|
319
|
+
filtered_notifications = filtered_notifications.later_than(Time.iso8601(options[:later_than]))
|
|
320
|
+
end
|
|
321
|
+
if options.has_key?(:earlier_than)
|
|
322
|
+
filtered_notifications = filtered_notifications.earlier_than(Time.iso8601(options[:earlier_than]))
|
|
323
|
+
end
|
|
324
|
+
if options.has_key?(:custom_filter)
|
|
325
|
+
filtered_notifications = filtered_notifications.where(options[:custom_filter])
|
|
326
|
+
end
|
|
327
|
+
filtered_notifications
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
# Orders by latest (newest) first as created_at: :desc.
|
|
331
|
+
# It uses sort key of Global Secondary Index in DynamoDB tables.
|
|
332
|
+
# @return [Dynamoid::Criteria::Chain] Database query of notifications or subscriptions ordered by latest first
|
|
333
|
+
def latest_order
|
|
334
|
+
# order(created_at: :desc)
|
|
335
|
+
scan_index_forward(false)
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
# Orders by earliest (older) first as created_at: :asc.
|
|
339
|
+
# It uses sort key of Global Secondary Index in DynamoDB tables.
|
|
340
|
+
# @return [Dynamoid::Criteria::Chain] Database query of notifications or subscriptions ordered by earliest first
|
|
341
|
+
def earliest_order
|
|
342
|
+
# order(created_at: :asc)
|
|
343
|
+
scan_index_forward(true)
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
# Orders by latest (newest) first as created_at: :desc and returns as array.
|
|
347
|
+
# @param [Boolean] reverse If notifications or subscriptions will be ordered as earliest first
|
|
348
|
+
# @return [Array] Array of notifications or subscriptions ordered by latest first
|
|
349
|
+
def latest_order!(reverse = false)
|
|
350
|
+
# order(created_at: :desc)
|
|
351
|
+
reverse ? earliest_order! : earliest_order!.reverse
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
# Orders by earliest (older) first as created_at: :asc and returns as array.
|
|
355
|
+
# It does not use sort key in DynamoDB tables.
|
|
356
|
+
# @return [Array] Array of notifications or subscriptions ordered by earliest first
|
|
357
|
+
def earliest_order!
|
|
358
|
+
# order(created_at: :asc)
|
|
359
|
+
all.to_a.sort_by {|n| n.created_at }
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
# Orders by latest (newest) first as subscribed_at: :desc.
|
|
363
|
+
# @return [Array] Array of subscriptions ordered by latest subscribed_at first
|
|
364
|
+
def latest_subscribed_order
|
|
365
|
+
# order(subscribed_at: :desc)
|
|
366
|
+
earliest_subscribed_order.reverse
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
# Orders by earliest (older) first as subscribed_at: :asc.
|
|
370
|
+
# @return [Array] Array of subscriptions ordered by earliest subscribed_at first
|
|
371
|
+
def earliest_subscribed_order
|
|
372
|
+
# order(subscribed_at: :asc)
|
|
373
|
+
all.to_a.sort_by {|n| n.subscribed_at }
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
# Orders by key name as key: :asc.
|
|
377
|
+
# @return [Array] Array of subscriptions ordered by key name
|
|
378
|
+
def key_order
|
|
379
|
+
# order(key: :asc)
|
|
380
|
+
all.to_a.sort_by {|n| n.key }
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
# Selects group owner notifications only.
|
|
384
|
+
# @scope class
|
|
385
|
+
# @return [Dynamoid::Criteria::Chain] Database query of filtered notifications
|
|
386
|
+
def group_owners_only
|
|
387
|
+
where('group_owner_id.null': true)
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
# Selects group member notifications only.
|
|
391
|
+
# @scope class
|
|
392
|
+
# @return [Dynamoid::Criteria::Chain] Database query of filtered notifications
|
|
393
|
+
def group_members_only
|
|
394
|
+
where('group_owner_id.not_null': true)
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
# Selects unopened notifications only.
|
|
398
|
+
# @scope class
|
|
399
|
+
# @return [Dynamoid::Criteria::Chain] Database query of filtered notifications
|
|
400
|
+
def unopened_only
|
|
401
|
+
where('opened_at.null': true)
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
# Selects opened notifications only without limit.
|
|
405
|
+
# Be careful to get too many records with this method.
|
|
406
|
+
# @scope class
|
|
407
|
+
# @return [Dynamoid::Criteria::Chain] Database query of filtered notifications
|
|
408
|
+
def opened_only!
|
|
409
|
+
where('opened_at.not_null': true)
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
# Selects opened notifications only with limit.
|
|
413
|
+
# @scope class
|
|
414
|
+
# @param [Integer] limit Limit to query for opened notifications
|
|
415
|
+
# @return [Dynamoid::Criteria::Chain] Database query of filtered notifications
|
|
416
|
+
def opened_only(limit)
|
|
417
|
+
limit == 0 ? none : opened_only!.limit(limit)
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
# Selects group member notifications in unopened_index.
|
|
421
|
+
# @scope class
|
|
422
|
+
# @return [Dynamoid::Criteria::Chain] Database query of filtered notifications
|
|
423
|
+
def unopened_index_group_members_only
|
|
424
|
+
group_owner_ids = unopened_index.map(&:id)
|
|
425
|
+
group_owner_ids.empty? ? none : where('group_owner_id.in': group_owner_ids)
|
|
426
|
+
end
|
|
427
|
+
|
|
428
|
+
# Selects group member notifications in opened_index.
|
|
429
|
+
# @scope class
|
|
430
|
+
# @param [Integer] limit Limit to query for opened notifications
|
|
431
|
+
# @return [Dynamoid::Criteria::Chain] Database query of filtered notifications
|
|
432
|
+
def opened_index_group_members_only(limit)
|
|
433
|
+
group_owner_ids = opened_index(limit).map(&:id)
|
|
434
|
+
group_owner_ids.empty? ? none : where('group_owner_id.in': group_owner_ids)
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
# Selects notifications within expiration.
|
|
438
|
+
# @scope class
|
|
439
|
+
# @param [ActiveSupport::Duration] expiry_delay Expiry period of notifications
|
|
440
|
+
# @return [Dynamoid::Criteria::Chain] Database query of filtered notifications
|
|
441
|
+
def within_expiration_only(expiry_delay)
|
|
442
|
+
where('created_at.gt': expiry_delay.ago)
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
# Selects group member notifications with specified group owner ids.
|
|
446
|
+
# @scope class
|
|
447
|
+
# @param [Array<String>] owner_ids Array of group owner ids
|
|
448
|
+
# @return [Dynamoid::Criteria::Chain] Database query of filtered notifications
|
|
449
|
+
def group_members_of_owner_ids_only(owner_ids)
|
|
450
|
+
owner_ids.present? ? where('group_owner_id.in': owner_ids) : none
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
# Includes target instance with query for notifications or subscriptions.
|
|
454
|
+
# @return [Dynamoid::Criteria::Chain] Database query of notifications with target
|
|
455
|
+
def with_target
|
|
456
|
+
self
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
# Includes notifiable instance with query for notifications.
|
|
460
|
+
# @return [Dynamoid::Criteria::Chain] Database query of notifications with notifiable
|
|
461
|
+
def with_notifiable
|
|
462
|
+
self
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
# Includes group instance with query for notifications.
|
|
466
|
+
# @return [Dynamoid::Criteria::Chain] Database query of notifications with group
|
|
467
|
+
def with_group
|
|
468
|
+
self
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
# Includes group owner instances with query for notifications.
|
|
472
|
+
# @return [Dynamoid::Criteria::Chain] Database query of notifications with group owner
|
|
473
|
+
def with_group_owner
|
|
474
|
+
self
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
# Includes group member instances with query for notifications.
|
|
478
|
+
# @return [Dynamoid::Criteria::Chain] Database query of notifications with group members
|
|
479
|
+
def with_group_members
|
|
480
|
+
self
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
# Includes notifier instance with query for notifications.
|
|
484
|
+
# @return [Dynamoid::Criteria::Chain] Database query of notifications with notifier
|
|
485
|
+
def with_notifier
|
|
486
|
+
self
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
# Dummy reload method for test of notifications or subscriptions.
|
|
490
|
+
def reload
|
|
491
|
+
self
|
|
492
|
+
end
|
|
493
|
+
|
|
494
|
+
# Returns latest notification instance.
|
|
495
|
+
# @return [Notification] Latest notification instance
|
|
496
|
+
def latest
|
|
497
|
+
latest_order.first
|
|
498
|
+
end
|
|
499
|
+
|
|
500
|
+
# Returns earliest notification instance.
|
|
501
|
+
# @return [Notification] Earliest notification instance
|
|
502
|
+
def earliest
|
|
503
|
+
earliest_order.first
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
# Returns latest notification instance.
|
|
507
|
+
# It does not use sort key in DynamoDB tables.
|
|
508
|
+
# @return [Notification] Latest notification instance
|
|
509
|
+
def latest!
|
|
510
|
+
latest_order!.first
|
|
511
|
+
end
|
|
512
|
+
|
|
513
|
+
# Returns earliest notification instance.
|
|
514
|
+
# It does not use sort key in DynamoDB tables.
|
|
515
|
+
# @return [Notification] Earliest notification instance
|
|
516
|
+
def earliest!
|
|
517
|
+
earliest_order!.first
|
|
518
|
+
end
|
|
519
|
+
|
|
520
|
+
# Selects unique keys from query for notifications or subscriptions.
|
|
521
|
+
# @return [Array<String>] Array of notification unique keys
|
|
522
|
+
def uniq_keys
|
|
523
|
+
all.to_a.collect {|n| n.key }.uniq
|
|
524
|
+
end
|
|
525
|
+
end
|
|
526
|
+
end
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
require_relative 'dynamoid/notification.rb'
|
|
530
|
+
require_relative 'dynamoid/subscription.rb'
|