activity_notification 1.7.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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 }