activity_notification 1.7.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +3 -0
  3. data/.travis.yml +16 -2
  4. data/CHANGELOG.md +22 -2
  5. data/Gemfile +7 -0
  6. data/Procfile +2 -0
  7. data/README.md +366 -32
  8. data/Rakefile +19 -10
  9. data/activity_notification.gemspec +5 -3
  10. data/app/channels/activity_notification/notification_channel.rb +37 -0
  11. data/app/channels/activity_notification/notification_with_devise_channel.rb +51 -0
  12. data/app/controllers/activity_notification/notifications_controller.rb +1 -1
  13. data/app/controllers/activity_notification/subscriptions_controller.rb +1 -1
  14. data/app/jobs/activity_notification/notify_all_job.rb +16 -0
  15. data/app/jobs/activity_notification/notify_job.rb +17 -0
  16. data/app/jobs/activity_notification/notify_to_job.rb +16 -0
  17. data/app/views/activity_notification/notifications/default/_default_without_grouping.html.erb +1 -1
  18. data/app/views/activity_notification/notifications/default/index.html.erb +55 -2
  19. data/bin/_dynamodblocal +4 -0
  20. data/{scripts → bin}/bundle_update.sh +1 -0
  21. data/bin/deploy_on_heroku.sh +14 -0
  22. data/bin/install_dynamodblocal.sh +5 -0
  23. data/bin/start_dynamodblocal.sh +47 -0
  24. data/bin/stop_dynamodblocal.sh +34 -0
  25. data/gemfiles/Gemfile.rails-4.2 +1 -0
  26. data/gemfiles/Gemfile.rails-5.0 +2 -0
  27. data/gemfiles/Gemfile.rails-5.1 +1 -0
  28. data/gemfiles/Gemfile.rails-5.2 +1 -0
  29. data/gemfiles/Gemfile.rails-6.0.rc +21 -0
  30. data/lib/activity_notification.rb +1 -0
  31. data/lib/activity_notification/apis/notification_api.rb +289 -136
  32. data/lib/activity_notification/apis/subscription_api.rb +80 -53
  33. data/lib/activity_notification/common.rb +3 -3
  34. data/lib/activity_notification/config.rb +89 -33
  35. data/lib/activity_notification/controllers/common_controller.rb +19 -7
  36. data/lib/activity_notification/helpers/errors.rb +4 -0
  37. data/lib/activity_notification/helpers/view_helpers.rb +1 -1
  38. data/lib/activity_notification/models/concerns/notifiable.rb +61 -53
  39. data/lib/activity_notification/models/concerns/subscriber.rb +7 -6
  40. data/lib/activity_notification/models/concerns/target.rb +73 -28
  41. data/lib/activity_notification/optional_targets/base.rb +2 -2
  42. data/lib/activity_notification/orm/active_record/notification.rb +4 -23
  43. data/lib/activity_notification/orm/dynamoid.rb +495 -0
  44. data/lib/activity_notification/orm/dynamoid/extension.rb +184 -0
  45. data/lib/activity_notification/orm/dynamoid/notification.rb +189 -0
  46. data/lib/activity_notification/orm/dynamoid/subscription.rb +82 -0
  47. data/lib/activity_notification/orm/mongoid.rb +4 -1
  48. data/lib/activity_notification/orm/mongoid/notification.rb +8 -25
  49. data/lib/activity_notification/orm/mongoid/subscription.rb +1 -1
  50. data/lib/activity_notification/roles/acts_as_notifiable.rb +33 -5
  51. data/lib/activity_notification/roles/acts_as_target.rb +62 -9
  52. data/lib/activity_notification/version.rb +1 -1
  53. data/lib/generators/templates/activity_notification.rb +30 -7
  54. data/lib/tasks/activity_notification_tasks.rake +14 -4
  55. data/spec/channels/notification_channel_shared_examples.rb +59 -0
  56. data/spec/channels/notification_channel_spec.rb +50 -0
  57. data/spec/channels/notification_with_devise_channel_spec.rb +99 -0
  58. data/spec/concerns/apis/notification_api_spec.rb +2 -2
  59. data/spec/concerns/apis/subscription_api_spec.rb +2 -2
  60. data/spec/concerns/models/notifiable_spec.rb +72 -7
  61. data/spec/concerns/models/subscriber_spec.rb +53 -49
  62. data/spec/concerns/models/target_spec.rb +135 -13
  63. data/spec/config_spec.rb +41 -1
  64. data/spec/controllers/notifications_controller_shared_examples.rb +7 -3
  65. data/spec/controllers/subscriptions_controller_shared_examples.rb +7 -3
  66. data/spec/helpers/view_helpers_spec.rb +12 -10
  67. data/spec/models/dummy/dummy_group_spec.rb +4 -0
  68. data/spec/models/dummy/dummy_notifiable_spec.rb +4 -0
  69. data/spec/models/dummy/dummy_notifier_spec.rb +4 -0
  70. data/spec/models/dummy/dummy_subscriber_spec.rb +3 -0
  71. data/spec/models/dummy/dummy_target_spec.rb +4 -0
  72. data/spec/models/notification_spec.rb +164 -45
  73. data/spec/models/subscription_spec.rb +69 -14
  74. data/spec/orm/dynamoid_spec.rb +115 -0
  75. data/spec/rails_app/app/assets/javascripts/application.js +2 -1
  76. data/spec/rails_app/app/assets/javascripts/cable.js +12 -0
  77. data/spec/rails_app/app/controllers/comments_controller.rb +3 -4
  78. data/spec/rails_app/app/models/admin.rb +6 -4
  79. data/spec/rails_app/app/models/article.rb +2 -2
  80. data/spec/rails_app/app/models/comment.rb +17 -5
  81. data/spec/rails_app/app/models/user.rb +5 -3
  82. data/spec/rails_app/app/views/activity_notification/notifications/users/overridden/custom/_test.html.erb +1 -0
  83. data/spec/rails_app/config/application.rb +6 -1
  84. data/spec/rails_app/config/cable.yml +8 -0
  85. data/spec/rails_app/config/dynamoid.rb +5 -0
  86. data/spec/rails_app/config/environment.rb +4 -1
  87. data/spec/rails_app/config/environments/production.rb +1 -1
  88. data/spec/rails_app/config/initializers/activity_notification.rb +30 -7
  89. data/spec/rails_app/config/locales/activity_notification.en.yml +2 -0
  90. data/spec/rails_app/db/seeds.rb +21 -5
  91. data/spec/rails_app/lib/mailer_previews/mailer_preview.rb +12 -4
  92. data/spec/roles/acts_as_notifiable_spec.rb +2 -2
  93. data/spec/roles/acts_as_target_spec.rb +1 -1
  94. data/spec/spec_helper.rb +15 -8
  95. metadata +67 -20
  96. data/spec/rails_app/app/models/.keep +0 -0
  97. data/spec/rails_app/app/views/activity_notification/notifications/users/overriden/custom/_test.html.erb +0 -1
@@ -4,55 +4,83 @@ module ActivityNotification
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  included do
7
- # Selects filtered subscriptions by key.
8
- # @example Get filtered subscriptions of the @user with key 'comment.reply'
9
- # @subscriptions = @user.subscriptions.filtered_by_key('comment.reply')
10
- # @scope class
11
- # @param [String] key Key of the subscription for filter
12
- # @return [ActiveRecord_AssociationRelation<Subscription>, Mongoid::Criteria<Notificaion>] Database query of filtered subscriptions
13
- scope :filtered_by_key, ->(key) { where(key: key) }
14
-
15
- # Selects filtered subscriptions by key with filter options.
16
- # @example Get filtered subscriptions of the @user with key 'comment.reply'
17
- # @subscriptions = @user.subscriptions.filtered_by_key('comment.reply')
18
- # @example Get custom filtered subscriptions of the @user
19
- # @subscriptions = @user.subscriptions.filtered_by_options({ custom_filter: ["created_at >= ?", time.hour.ago] })
20
- # @scope class
21
- # @param [Hash] options Options for filter
22
- # @option options [String] :filtered_by_key (nil) Key of the subscription for filter
23
- # @option options [Array|Hash] :custom_filter (nil) Custom subscription filter (e.g. ["created_at >= ?", time.hour.ago])
24
- # @return [ActiveRecord_AssociationRelation<Subscription>, Mongoid::Criteria<Notificaion>] Database query of filtered subscriptions
25
- scope :filtered_by_options, ->(options = {}) {
26
- options = ActivityNotification.cast_to_indifferent_hash(options)
27
- filtered_subscriptions = all
28
- if options.has_key?(:filtered_by_key)
29
- filtered_subscriptions = filtered_subscriptions.filtered_by_key(options[:filtered_by_key])
30
- end
31
- if options.has_key?(:custom_filter)
32
- filtered_subscriptions = filtered_subscriptions.where(options[:custom_filter])
7
+ # :only-rails5-plus#only-rails-with-callback-issue#except-dynamoid:
8
+ # :only-rails5-plus#only-rails-without-callback-issue#except-dynamoid:
9
+ # :except-rails5-plus#only-rails-with-callback-issue#except-dynamoid:
10
+ # :except-rails5-plus#only-rails-without-callback-issue#except-dynamoid:
11
+ unless ActivityNotification.config.orm == :dynamoid
12
+ # Selects filtered subscriptions by key.
13
+ # @example Get filtered subscriptions of the @user with key 'comment.reply'
14
+ # @subscriptions = @user.subscriptions.filtered_by_key('comment.reply')
15
+ # @scope class
16
+ # @param [String] key Key of the subscription for filter
17
+ # @return [ActiveRecord_AssociationRelation<Subscription>, Mongoid::Criteria<Notificaion>] Database query of filtered subscriptions
18
+ scope :filtered_by_key, ->(key) { where(key: key) }
19
+
20
+ # Selects filtered subscriptions by key with filter options.
21
+ # @example Get filtered subscriptions of the @user with key 'comment.reply'
22
+ # @subscriptions = @user.subscriptions.filtered_by_key('comment.reply')
23
+ # @example Get custom filtered subscriptions of the @user
24
+ # @subscriptions = @user.subscriptions.filtered_by_options({ custom_filter: ["created_at >= ?", time.hour.ago] })
25
+ # @scope class
26
+ # @param [Hash] options Options for filter
27
+ # @option options [String] :filtered_by_key (nil) Key of the subscription for filter
28
+ # @option options [Array|Hash] :custom_filter (nil) Custom subscription filter (e.g. ["created_at >= ?", time.hour.ago] or ['created_at.gt': time.hour.ago])
29
+ # @return [ActiveRecord_AssociationRelation<Subscription>, Mongoid::Criteria<Notificaion>] Database query of filtered subscriptions
30
+ scope :filtered_by_options, ->(options = {}) {
31
+ options = ActivityNotification.cast_to_indifferent_hash(options)
32
+ filtered_subscriptions = all
33
+ if options.has_key?(:filtered_by_key)
34
+ filtered_subscriptions = filtered_subscriptions.filtered_by_key(options[:filtered_by_key])
35
+ end
36
+ if options.has_key?(:custom_filter)
37
+ filtered_subscriptions = filtered_subscriptions.where(options[:custom_filter])
38
+ end
39
+ filtered_subscriptions
40
+ }
41
+
42
+ # Orders by latest (newest) first as created_at: :desc.
43
+ # @return [ActiveRecord_AssociationRelation<Subscription>, Mongoid::Criteria<Notificaion>] Database query of subscriptions ordered by latest first
44
+ scope :latest_order, -> { order(created_at: :desc) }
45
+
46
+ # Orders by earliest (older) first as created_at: :asc.
47
+ # @return [ActiveRecord_AssociationRelation<Subscription>, Mongoid::Criteria<Notificaion>] Database query of subscriptions ordered by earliest first
48
+ scope :earliest_order, -> { order(created_at: :asc) }
49
+
50
+ # Orders by latest (newest) first as created_at: :desc.
51
+ # This method is to be overridden in implementation for each ORM.
52
+ # @param [Boolean] reverse If subscriptions will be ordered as earliest first
53
+ # @return [ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>] Database query of ordered subscriptions
54
+ scope :latest_order!, ->(reverse = false) { reverse ? earliest_order : latest_order }
55
+
56
+ # Orders by earliest (older) first as created_at: :asc.
57
+ # This method is to be overridden in implementation for each ORM.
58
+ # @return [ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>] Database query of subscriptions ordered by earliest first
59
+ scope :earliest_order!, -> { earliest_order }
60
+
61
+ # Orders by latest (newest) first as subscribed_at: :desc.
62
+ # @return [ActiveRecord_AssociationRelation<Subscription>, Mongoid::Criteria<Notificaion>] Database query of subscriptions ordered by latest subscribed_at first
63
+ scope :latest_subscribed_order, -> { order(subscribed_at: :desc) }
64
+
65
+ # Orders by earliest (older) first as subscribed_at: :asc.
66
+ # @return [ActiveRecord_AssociationRelation<Subscription>, Mongoid::Criteria<Notificaion>] Database query of subscriptions ordered by earliest subscribed_at first
67
+ scope :earliest_subscribed_order, -> { order(subscribed_at: :asc) }
68
+
69
+ # Orders by key name as key: :asc.
70
+ # @return [ActiveRecord_AssociationRelation<Subscription>, Mongoid::Criteria<Notificaion>] Database query of subscriptions ordered by key name
71
+ scope :key_order, -> { order(key: :asc) }
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 [Time, Object] Converted Time value
76
+ def self.convert_time_as_hash(time)
77
+ time
33
78
  end
34
- filtered_subscriptions
35
- }
36
-
37
- # Orders by latest (newest) first as created_at: :desc.
38
- # @return [ActiveRecord_AssociationRelation<Subscription>, Mongoid::Criteria<Notificaion>] Database query of subscriptions ordered by latest first
39
- scope :latest_order, -> { order(created_at: :desc) }
40
-
41
- # Orders by earliest (older) first as created_at: :asc.
42
- # @return [ActiveRecord_AssociationRelation<Subscription>, Mongoid::Criteria<Notificaion>] Database query of subscriptions ordered by earliest first
43
- scope :earliest_order, -> { order(created_at: :asc) }
44
-
45
- # Orders by latest (newest) first as subscribed_at: :desc.
46
- # @return [ActiveRecord_AssociationRelation<Subscription>, Mongoid::Criteria<Notificaion>] Database query of subscriptions ordered by latest subscribed_at first
47
- scope :latest_subscribed_order, -> { order(subscribed_at: :desc) }
48
-
49
- # Orders by earliest (older) first as subscribed_at: :asc.
50
- # @return [ActiveRecord_AssociationRelation<Subscription>, Mongoid::Criteria<Notificaion>] Database query of subscriptions ordered by earliest subscribed_at first
51
- scope :earliest_subscribed_order, -> { order(subscribed_at: :asc) }
52
-
53
- # Orders by key name as key: :asc.
54
- # @return [ActiveRecord_AssociationRelation<Subscription>, Mongoid::Criteria<Notificaion>] Database query of subscriptions ordered by key name
55
- scope :key_order, -> { order(key: :asc) }
79
+ end
80
+ # :only-rails5-plus#only-rails-with-callback-issue#except-dynamoid:
81
+ # :only-rails5-plus#only-rails-without-callback-issue#except-dynamoid:
82
+ # :except-rails5-plus#only-rails-with-callback-issue#except-dynamoid:
83
+ # :except-rails5-plus#only-rails-without-callback-issue#except-dynamoid:
56
84
  end
57
85
 
58
86
  class_methods do
@@ -95,7 +123,7 @@ module ActivityNotification
95
123
  optional_target_names.each do |optional_target_name|
96
124
  new_attributes[:optional_targets] = new_attributes[:optional_targets].merge(
97
125
  Subscription.to_optional_target_key(optional_target_name) => true,
98
- Subscription.to_optional_target_subscribed_at_key(optional_target_name) => subscribed_at)
126
+ Subscription.to_optional_target_subscribed_at_key(optional_target_name) => Subscription.convert_time_as_hash(subscribed_at))
99
127
  end
100
128
  end
101
129
  update(new_attributes)
@@ -114,7 +142,7 @@ module ActivityNotification
114
142
  optional_target_names.each do |optional_target_name|
115
143
  new_attributes[:optional_targets] = new_attributes[:optional_targets].merge(
116
144
  Subscription.to_optional_target_key(optional_target_name) => false,
117
- Subscription.to_optional_target_unsubscribed_at_key(optional_target_name) => subscribed_at)
145
+ Subscription.to_optional_target_unsubscribed_at_key(optional_target_name) => Subscription.convert_time_as_hash(subscribed_at))
118
146
  end
119
147
  update(new_attributes)
120
148
  end
@@ -161,7 +189,7 @@ module ActivityNotification
161
189
  subscribed_at = options[:subscribed_at] || Time.current
162
190
  update(optional_targets: optional_targets.merge(
163
191
  Subscription.to_optional_target_key(optional_target_name) => true,
164
- Subscription.to_optional_target_subscribed_at_key(optional_target_name) => subscribed_at)
192
+ Subscription.to_optional_target_subscribed_at_key(optional_target_name) => Subscription.convert_time_as_hash(subscribed_at))
165
193
  )
166
194
  end
167
195
 
@@ -175,7 +203,7 @@ module ActivityNotification
175
203
  unsubscribed_at = options[:unsubscribed_at] || Time.current
176
204
  update(optional_targets: optional_targets.merge(
177
205
  Subscription.to_optional_target_key(optional_target_name) => false,
178
- Subscription.to_optional_target_unsubscribed_at_key(optional_target_name) => unsubscribed_at)
206
+ Subscription.to_optional_target_unsubscribed_at_key(optional_target_name) => Subscription.convert_time_as_hash(unsubscribed_at))
179
207
  )
180
208
  end
181
209
 
@@ -185,7 +213,6 @@ module ActivityNotification
185
213
  optional_targets.keys.select { |key| key.to_s.start_with?("subscribing_to_") }.map { |key| key.slice(15..-1) }
186
214
  end
187
215
 
188
-
189
216
  protected
190
217
 
191
218
  # Validates subscribing_to_email cannot be true when subscribing is false.
@@ -106,20 +106,20 @@ module ActivityNotification
106
106
  # Convets to singularized model name (resource name).
107
107
  # @return [String] Singularized model name (resource name)
108
108
  def to_resource_name
109
- self.class.name.demodulize.singularize.underscore
109
+ self.to_class_name.demodulize.singularize.underscore
110
110
  end
111
111
 
112
112
  # Convets to pluralized model name (resources name).
113
113
  # @return [String] Pluralized model name (resources name)
114
114
  def to_resources_name
115
- self.class.name.demodulize.pluralize.underscore
115
+ self.to_class_name.demodulize.pluralize.underscore
116
116
  end
117
117
 
118
118
  # Convets to printable model type name to be humanized.
119
119
  # @return [String] Printable model type name
120
120
  # @todo Is this the best to make readable?
121
121
  def printable_type
122
- "#{self.class.name.demodulize.humanize}"
122
+ "#{self.to_class_name.demodulize.humanize}"
123
123
  end
124
124
 
125
125
  # Convets to printable model name to show in view or email.
@@ -1,6 +1,12 @@
1
1
  module ActivityNotification
2
2
  # Class used to initialize configuration object.
3
3
  class Config
4
+
5
+ # @overload :orm
6
+ # Returns ORM name for ActivityNotification (:active_record, :mongoid or :dynamodb)
7
+ # @return [Boolean] ORM name for ActivityNotification (:active_record, :mongoid or :dynamodb).
8
+ attr_reader :orm
9
+
4
10
  # @overload enabled
5
11
  # Returns whether ActivityNotification is enabled
6
12
  # @return [Boolean] Whether ActivityNotification is enabled.
@@ -10,16 +16,6 @@ module ActivityNotification
10
16
  # @return [Boolean] Whether ActivityNotification is enabled.
11
17
  attr_accessor :enabled
12
18
 
13
- # @deprecated as of 1.1.0
14
- # @overload table_name
15
- # Returns table name to store notifications
16
- # @return [String] Table name to store notifications.
17
- # @overload table_name=(value)
18
- # Sets table name to store notifications
19
- # @param [String] table_name The new notification_table_name
20
- # @return [String] Table name to store notifications.
21
- attr_accessor :table_name
22
-
23
19
  # @overload notification_table_name
24
20
  # Returns table name to store notifications
25
21
  # @return [String] Table name to store notifications.
@@ -110,6 +106,15 @@ module ActivityNotification
110
106
  # @return [String] Base controller class for notifications_controller.
111
107
  attr_accessor :parent_controller
112
108
 
109
+ # @overload parent_channel
110
+ # Returns base channel class for notification_channel
111
+ # @return [String] Base channel class for notification_channel.
112
+ # @overload parent_channel=(value)
113
+ # Sets base channel class for notification_channel
114
+ # @param [String] parent_channel The new parent_channel
115
+ # @return [String] Base channel class for notification_channel.
116
+ attr_accessor :parent_channel
117
+
113
118
  # @overload mailer_templates_dir
114
119
  # Returns custom mailer templates directory
115
120
  # @return [String] Custom mailer templates directory.
@@ -137,37 +142,88 @@ module ActivityNotification
137
142
  # @return [Symbol] ActiveJob queue name for delayed notifications.
138
143
  attr_accessor :active_job_queue
139
144
 
140
- # @overload :orm
141
- # Returns ORM name for ActivityNotification (:active_record or :mongoid)
142
- # @return [Boolean] ORM name for ActivityNotification (:active_record or :mongoid).
143
- attr_reader :orm
145
+ # @overload composite_key_delimiter
146
+ # Returns Delimiter of composite key for DynamoDB
147
+ # @return [String] Delimiter of composite key for DynamoDB.
148
+ # @overload composite_key_delimiter=(value)
149
+ # Sets delimiter of composite key for DynamoDB
150
+ # @param [Symbol] composite_key_delimiter The new delimiter of composite key for DynamoDB
151
+ # @return [Symbol] Delimiter of composite key for DynamoDB.
152
+ attr_accessor :composite_key_delimiter
153
+
154
+ # @overload store_with_associated_records
155
+ # Returns whether activity_notification stores notificaion records including associated records like target and notifiable
156
+ # @return [Boolean] Whether activity_notification stores notificaion records including associated records like target and notifiable.
157
+ attr_reader :store_with_associated_records
158
+
159
+ # @overload action_cable_enabled
160
+ # Returns whether WebSocket subscription using ActionCable is enabled
161
+ # @return [Boolean] Whether WebSocket subscription using ActionCable is enabled.
162
+ # @overload action_cable_enabled=(value)
163
+ # Sets whether WebSocket subscription using ActionCable is enabled
164
+ # @param [Boolean] action_cable_enabled The new action_cable_enabled
165
+ # @return [Boolean] Whether WebSocket subscription using ActionCable is enabled.
166
+ attr_accessor :action_cable_enabled
167
+
168
+ # @overload action_cable_with_devise
169
+ # Returns whether activity_notification publishes WebSocket notifications using ActionCable only to authenticated target with Devise
170
+ # @return [Boolean] Whether activity_notification publishes WebSocket notifications using ActionCable only to authenticated target with Devise.
171
+ # @overload action_cable_with_devise=(value)
172
+ # Sets whether activity_notification publishes WebSocket notifications using ActionCable only to authenticated target with Devise
173
+ # @param [Boolean] action_cable_with_devise The new action_cable_with_devise
174
+ # @return [Boolean] Whether activity_notification publishes WebSocket notifications using ActionCable only to authenticated target with Devise.
175
+ attr_accessor :action_cable_with_devise
176
+
177
+ # @overload notification_channel_prefix
178
+ # Returns notification channel prefix for ActionCable
179
+ # @return [String] Notification channel prefix for ActionCable.
180
+ # @overload notification_channel_prefix=(value)
181
+ # Sets notification channel prefix for ActionCable
182
+ # @param [String] notification_channel_prefix The new notification_channel_prefix
183
+ # @return [String] Notification channel prefix for ActionCable.
184
+ attr_accessor :notification_channel_prefix
144
185
 
145
186
  # Initialize configuration for ActivityNotification.
146
- # These configuration can be overriden in initializer.
187
+ # These configuration can be overridden in initializer.
147
188
  # @return [Config] A new instance of Config
148
189
  def initialize
149
- @enabled = true
150
- @notification_table_name = 'notifications'
151
- @subscription_table_name = 'subscriptions'
152
- @email_enabled = false
153
- @subscription_enabled = false
154
- @subscribe_as_default = true
155
- @mailer_sender = nil
156
- @mailer = 'ActivityNotification::Mailer'
157
- @parent_mailer = 'ActionMailer::Base'
158
- @parent_job = 'ActiveJob::Base'
159
- @parent_controller = 'ApplicationController'
160
- @mailer_templates_dir = 'activity_notification/mailer'
161
- @opened_index_limit = 10
162
- @active_job_queue = :activity_notification
163
- @orm = :active_record
190
+ @enabled = true
191
+ @orm = :active_record
192
+ @notification_table_name = 'notifications'
193
+ @subscription_table_name = 'subscriptions'
194
+ @email_enabled = false
195
+ @subscription_enabled = false
196
+ @subscribe_as_default = true
197
+ @mailer_sender = nil
198
+ @mailer = 'ActivityNotification::Mailer'
199
+ @parent_mailer = 'ActionMailer::Base'
200
+ @parent_job = 'ActiveJob::Base'
201
+ @parent_controller = 'ApplicationController'
202
+ @parent_channel = 'ActionCable::Channel::Base'
203
+ @mailer_templates_dir = 'activity_notification/mailer'
204
+ @opened_index_limit = 10
205
+ @active_job_queue = :activity_notification
206
+ @composite_key_delimiter = '#'
207
+ @store_with_associated_records = false
208
+ @action_cable_enabled = false
209
+ @action_cable_with_devise = false
210
+ @notification_channel_prefix = 'activity_notification_channel'
164
211
  end
165
212
 
166
- # Sets ORM name for ActivityNotification (:active_record or :mongoid)
167
- # @param [Symbol, String] orm The new ORM name for ActivityNotification (:active_record or :mongoid)
168
- # @return [Symbol] ORM name for ActivityNotification (:active_record or :mongoid).
213
+ # Sets ORM name for ActivityNotification (:active_record, :mongoid or :dynamodb)
214
+ # @param [Symbol, String] orm The new ORM name for ActivityNotification (:active_record, :mongoid or :dynamodb)
215
+ # @return [Symbol] ORM name for ActivityNotification (:active_record, :mongoid or :dynamodb).
169
216
  def orm=(orm)
170
217
  @orm = orm.to_sym
171
218
  end
219
+
220
+ # Sets whether activity_notification stores notificaion records including associated records like target and notifiable.
221
+ # This store_with_associated_records option can be set true only when you use mongoid or dynamoid ORM.
222
+ # @param [Boolean] store_with_associated_records The new store_with_associated_records
223
+ # @return [Boolean] Whether activity_notification stores notificaion records including associated records like target and notifiable.
224
+ def store_with_associated_records=(store_with_associated_records)
225
+ if store_with_associated_records && [:mongoid, :dynamoid].exclude?(@orm) then raise ActivityNotification::ConfigError, "config.store_with_associated_records can be set true only when you use mongoid or dynamoid ORM." end
226
+ @store_with_associated_records = store_with_associated_records
227
+ end
172
228
  end
173
229
  end
@@ -42,7 +42,7 @@ module ActivityNotification
42
42
  end
43
43
 
44
44
  # Sets options to load resource index from request parameters.
45
- # This method is to be overriden.
45
+ # This method is to be overridden.
46
46
  # @api protected
47
47
  # @return [Hash] options to load resource index
48
48
  def set_index_options
@@ -50,7 +50,7 @@ module ActivityNotification
50
50
  end
51
51
 
52
52
  # Loads resource index with request parameters.
53
- # This method is to be overriden.
53
+ # This method is to be overridden.
54
54
  # @api protected
55
55
  # @return [Array] Array of resource index
56
56
  def load_index
@@ -58,7 +58,7 @@ module ActivityNotification
58
58
  end
59
59
 
60
60
  # Returns controller path.
61
- # This method is called from target_view_path method and can be overriden.
61
+ # This method is called from target_view_path method and can be overridden.
62
62
  # @api protected
63
63
  # @return [String] "activity_notification" as controller path
64
64
  def controller_path
@@ -101,17 +101,29 @@ module ActivityNotification
101
101
  # @api protected
102
102
  # @return [Boolean] True
103
103
  def compatibly_redirect_back(request_params = {})
104
- # :only-rails5+:
104
+ # :only-rails5-plus#only-rails-with-callback-issue:
105
+ # :only-rails5-plus#only-rails-without-callback-issue:
106
+ # :only-rails5-plus#only-rails-with-callback-issue#except-dynamoid:
107
+ # :only-rails5-plus#only-rails-without-callback-issue#except-dynamoid:
105
108
  if Rails::VERSION::MAJOR >= 5
106
109
  redirect_back fallback_location: { action: :index }, **request_params
107
- # :only-rails5+:
108
- # :except-rails5+:
110
+ # :only-rails5-plus#only-rails-with-callback-issue:
111
+ # :only-rails5-plus#only-rails-without-callback-issue:
112
+ # :only-rails5-plus#only-rails-with-callback-issue#except-dynamoid:
113
+ # :only-rails5-plus#only-rails-without-callback-issue#except-dynamoid:
114
+ # :except-rails5-plus#only-rails-with-callback-issue:
115
+ # :except-rails5-plus#only-rails-without-callback-issue:
116
+ # :except-rails5-plus#only-rails-with-callback-issue#except-dynamoid:
117
+ # :except-rails5-plus#only-rails-without-callback-issue#except-dynamoid:
109
118
  elsif request.referer
110
119
  redirect_to :back, **request_params
111
120
  else
112
121
  redirect_to action: :index, **request_params
113
122
  end
114
- # :except-rails5+:
123
+ # :except-rails5-plus#only-rails-with-callback-issue:
124
+ # :except-rails5-plus#only-rails-without-callback-issue:
125
+ # :except-rails5-plus#only-rails-with-callback-issue#except-dynamoid:
126
+ # :except-rails5-plus#only-rails-without-callback-issue#except-dynamoid:
115
127
  true
116
128
  end
117
129
  end
@@ -0,0 +1,4 @@
1
+ module ActivityNotification
2
+ class ConfigError < StandardError; end
3
+ class DeleteRestrictionError < StandardError; end
4
+ end
@@ -18,7 +18,7 @@ module ActivityNotification
18
18
  if notifications.is_a? ActivityNotification::Notification
19
19
  notifications.render self, options
20
20
  elsif notifications.respond_to?(:map)
21
- return nil if notifications.empty?
21
+ return nil if (notifications.respond_to?(:empty?) ? notifications.empty? : notifications.to_a.empty?)
22
22
  notifications.map {|notification| notification.render self, options.dup }.join.html_safe
23
23
  end
24
24
  end
@@ -12,22 +12,23 @@ module ActivityNotification
12
12
  include Rails.application.routes.url_helpers
13
13
 
14
14
  # Has many notification instances for this notifiable.
15
- # Dependency for these notifications can be overriden from acts_as_notifiable.
15
+ # Dependency for these notifications can be overridden from acts_as_notifiable.
16
16
  # @scope instance
17
17
  # @return [Array<Notificaion>, Mongoid::Criteria<Notificaion>] Array or database query of notifications for this notifiable
18
18
  has_many_records :generated_notifications_as_notifiable,
19
19
  class_name: "::ActivityNotification::Notification",
20
20
  as: :notifiable
21
21
 
22
- class_attribute :_notification_targets,
23
- :_notification_group,
24
- :_notification_group_expiry_delay,
25
- :_notifier,
26
- :_notification_parameters,
27
- :_notification_email_allowed,
28
- :_notifiable_path,
29
- :_printable_notifiable_name,
30
- :_optional_targets
22
+ class_attribute :_notification_targets,
23
+ :_notification_group,
24
+ :_notification_group_expiry_delay,
25
+ :_notifier,
26
+ :_notification_parameters,
27
+ :_notification_email_allowed,
28
+ :_notification_action_cable_allowed,
29
+ :_notifiable_path,
30
+ :_printable_notifiable_name,
31
+ :_optional_targets
31
32
  set_notifiable_class_defaults
32
33
  end
33
34
 
@@ -47,21 +48,22 @@ module ActivityNotification
47
48
  # Sets default values to notifiable class fields.
48
49
  # @return [NilClass] nil
49
50
  def set_notifiable_class_defaults
50
- self._notification_targets = {}
51
- self._notification_group = {}
52
- self._notification_group_expiry_delay = {}
53
- self._notifier = {}
54
- self._notification_parameters = {}
55
- self._notification_email_allowed = {}
56
- self._notifiable_path = {}
57
- self._printable_notifiable_name = {}
58
- self._optional_targets = {}
51
+ self._notification_targets = {}
52
+ self._notification_group = {}
53
+ self._notification_group_expiry_delay = {}
54
+ self._notifier = {}
55
+ self._notification_parameters = {}
56
+ self._notification_email_allowed = {}
57
+ self._notification_action_cable_allowed = {}
58
+ self._notifiable_path = {}
59
+ self._printable_notifiable_name = {}
60
+ self._optional_targets = {}
59
61
  nil
60
62
  end
61
63
  end
62
64
 
63
- # Returns notification targets from configured field or overriden method.
64
- # This method is able to be overriden.
65
+ # Returns notification targets from configured field or overridden method.
66
+ # This method is able to be overridden.
65
67
  #
66
68
  # @param [String] target_type Target type to notify
67
69
  # @param [Hash] options Options for notifications
@@ -82,8 +84,8 @@ module ActivityNotification
82
84
  resolved_parameter
83
85
  end
84
86
 
85
- # Returns group unit of the notifications from configured field or overriden method.
86
- # This method is able to be overriden.
87
+ # Returns group unit of the notifications from configured field or overridden method.
88
+ # This method is able to be overridden.
87
89
  #
88
90
  # @param [String] target_type Target type to notify
89
91
  # @param [String] key Key of the notification
@@ -96,8 +98,8 @@ module ActivityNotification
96
98
  key)
97
99
  end
98
100
 
99
- # Returns group expiry period of the notifications from configured field or overriden method.
100
- # This method is able to be overriden.
101
+ # Returns group expiry period of the notifications from configured field or overridden method.
102
+ # This method is able to be overridden.
101
103
  #
102
104
  # @param [String] target_type Target type to notify
103
105
  # @param [String] key Key of the notification
@@ -110,8 +112,8 @@ module ActivityNotification
110
112
  key)
111
113
  end
112
114
 
113
- # Returns additional notification parameters from configured field or overriden method.
114
- # This method is able to be overriden.
115
+ # Returns additional notification parameters from configured field or overridden method.
116
+ # This method is able to be overridden.
115
117
  #
116
118
  # @param [String] target_type Target type to notify
117
119
  # @param [String] key Key of the notification
@@ -124,8 +126,8 @@ module ActivityNotification
124
126
  key)
125
127
  end
126
128
 
127
- # Returns notifier of the notification from configured field or overriden method.
128
- # This method is able to be overriden.
129
+ # Returns notifier of the notification from configured field or overridden method.
130
+ # This method is able to be overridden.
129
131
  #
130
132
  # @param [String] target_type Target type to notify
131
133
  # @param [String] key Key of the notification
@@ -138,8 +140,8 @@ module ActivityNotification
138
140
  key)
139
141
  end
140
142
 
141
- # Returns if sending notification email is allowed for the notifiable from configured field or overriden method.
142
- # This method is able to be overriden.
143
+ # Returns if sending notification email is allowed for the notifiable from configured field or overridden method.
144
+ # This method is able to be overridden.
143
145
  #
144
146
  # @param [Object] target Target instance to notify
145
147
  # @param [String] key Key of the notification
@@ -152,8 +154,22 @@ module ActivityNotification
152
154
  target, key)
153
155
  end
154
156
 
155
- # Returns notifiable_path to move after opening notification from configured field or overriden method.
156
- # This method is able to be overriden.
157
+ # Returns if publishing WebSocket using ActionCable is allowed for the notifiable from configured field or overridden method.
158
+ # This method is able to be overridden.
159
+ #
160
+ # @param [Object] target Target instance to notify
161
+ # @param [String] key Key of the notification
162
+ # @return [Boolean] If publishing WebSocket using ActionCable is allowed for the notifiable
163
+ def notification_action_cable_allowed?(target, key = nil)
164
+ resolve_parameter(
165
+ "notification_action_cable_allowed_for_#{cast_to_resources_name(target.class)}?",
166
+ _notification_action_cable_allowed[cast_to_resources_sym(target.class)],
167
+ ActivityNotification.config.action_cable_enabled,
168
+ target, key)
169
+ end
170
+
171
+ # Returns notifiable_path to move after opening notification from configured field or overridden method.
172
+ # This method is able to be overridden.
157
173
  #
158
174
  # @param [String] target_type Target type to notify
159
175
  # @param [String] key Key of the notification
@@ -186,8 +202,8 @@ module ActivityNotification
186
202
  target, key)
187
203
  end
188
204
 
189
- # Returns optional_targets of the notification from configured field or overriden method.
190
- # This method is able to be overriden.
205
+ # Returns optional_targets of the notification from configured field or overridden method.
206
+ # This method is able to be overridden.
191
207
  #
192
208
  # @param [String] target_type Target type to notify
193
209
  # @param [String] key Key of the notification
@@ -200,8 +216,8 @@ module ActivityNotification
200
216
  key)
201
217
  end
202
218
 
203
- # Returns optional_target names of the notification from configured field or overriden method.
204
- # This method is able to be overriden.
219
+ # Returns optional_target names of the notification from configured field or overridden method.
220
+ # This method is able to be overridden.
205
221
  #
206
222
  # @param [String] target_type Target type to notify
207
223
  # @param [String] key Key of the notification
@@ -353,7 +369,7 @@ module ActivityNotification
353
369
  end
354
370
 
355
371
  # Returns default key of the notification.
356
- # This method is able to be overriden.
372
+ # This method is able to be overridden.
357
373
  # "#{to_resource_name}.default" is defined as default key.
358
374
  #
359
375
  # @return [String] Default key of the notification
@@ -362,7 +378,7 @@ module ActivityNotification
362
378
  end
363
379
 
364
380
  # Returns key of the notification for tracked notifiable creation.
365
- # This method is able to be overriden.
381
+ # This method is able to be overridden.
366
382
  # "#{to_resource_name}.create" is defined as default creation key.
367
383
  #
368
384
  # @return [String] Key of the notification for tracked notifiable creation
@@ -371,7 +387,7 @@ module ActivityNotification
371
387
  end
372
388
 
373
389
  # Returns key of the notification for tracked notifiable update.
374
- # This method is able to be overriden.
390
+ # This method is able to be overridden.
375
391
  # "#{to_resource_name}.update" is defined as default update key.
376
392
  #
377
393
  # @return [String] Key of the notification for tracked notifiable update
@@ -384,10 +400,10 @@ module ActivityNotification
384
400
  # Used to transform parameter value from configured field or defined method.
385
401
  # @api private
386
402
  #
387
- # @param [String] target_typed_method_name Method name overriden for the target type
403
+ # @param [String] target_typed_method_name Method name overridden for the target type
388
404
  # @param [Object] parameter_field Parameter Configured field in this model
389
405
  # @param [Object] default_value Default parameter value
390
- # @param [Array] args Arguments to pass to the method overriden or defined as parameter field
406
+ # @param [Array] args Arguments to pass to the method overridden or defined as parameter field
391
407
  # @return [Object] Resolved parameter value
392
408
  def resolve_parameter(target_typed_method_name, parameter_field, default_value, *args)
393
409
  if respond_to?(target_typed_method_name)
@@ -419,20 +435,12 @@ module ActivityNotification
419
435
  generated_notifications = generated_notifications_as_notifiable_for(target_type)
420
436
  case dependent
421
437
  when :restrict_with_exception
422
- ActivityNotification::Notification.raise_delete_restriction_error("generated_notifications_as_notifiable_for_#{target_type.to_s.pluralize.underscore}") unless generated_notifications.empty?
438
+ ActivityNotification::Notification.raise_delete_restriction_error("generated_notifications_as_notifiable_for_#{target_type.to_s.pluralize.underscore}") unless generated_notifications.to_a.empty?
423
439
  when :restrict_with_error
424
- unless generated_notifications.empty?
440
+ unless generated_notifications.to_a.empty?
425
441
  record = self.class.human_attribute_name("generated_notifications_as_notifiable_for_#{target_type.to_s.pluralize.underscore}").downcase
426
442
  self.errors.add(:base, :'restrict_dependent_destroy.has_many', record: record)
427
- # :only-rails5+:
428
- if Rails::VERSION::MAJOR >= 5
429
- throw(:abort)
430
- # :only-rails5+:
431
- # :except-rails5+:
432
- else
433
- false
434
- end
435
- # :except-rails5+:
443
+ if Rails::VERSION::MAJOR >= 5 then throw(:abort) else false end
436
444
  end
437
445
  when :destroy
438
446
  generated_notifications.each { |n| n.destroy }