notification-handler 2.0.0 → 4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f2cdb58ba8f4da880b60d9443747199aac809a9fc881c52ea6d6521b02ebb1c6
4
- data.tar.gz: 2b22c562259da40608261bd742224fc6302ba678e2536ece9c01a01a01c51d82
3
+ metadata.gz: c20f9c7a594694c319f373377455d5acfa641e83f761c4af1026eb0373b61393
4
+ data.tar.gz: a8e467f20f1a34ae3cfd544179354f7dc826feb05e17937ae3854a7441b54265
5
5
  SHA512:
6
- metadata.gz: a6eb0d2c4cc82ca45ca54d08bc4bf75aaa531d793a31109c0644345e2e00d392f84bf145b414863b835225e52a2249d64ff12df872b2698657ba6ce0b7401693
7
- data.tar.gz: cac446fcf48614af0346f947a181be5bfbb5a2fe9f54dd3aebd7e0b231d2550d73f851fad439cf3a07565e8daa9f7278ccc9c5ddd59395b8ee82a1d8e9d50aea
6
+ metadata.gz: 4368450b8c8bbdc11defc79f74a46bc3338c414e493419c46e5e37e041c81e968b7264cc365d34be3ad24170fa6440bac471df571cc745db6fb2ec311a5034ba
7
+ data.tar.gz: 75e5ab81337e515b9ae86234f9290335fe6bc58c7929c3b849c31749a9adfe429460279f3836f0a10f3dca5a14c22012d681bbea0d32e978a95187d57bf2ee58
data/README.md CHANGED
@@ -1,228 +1,84 @@
1
- # NotificationHandler
1
+ # notifications-rails
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/notification-handler.svg)](https://badge.fury.io/rb/notification-handler) ![Travis](https://travis-ci.com/jonhue/notifications-rails.svg?branch=master)
3
+ A flexible notification library supporting the delivery to external services, rendering in various environments, and user configuration by category.
4
4
 
5
- Create and modify your notifications through a simple API.
5
+ ## Philosophy
6
6
 
7
- ---
7
+ notifications-rails has been built with modularity in mind. It currently consists of four components each of which bringing one essential functionality to the integration of notifications in your Rails app.
8
8
 
9
- ## Table of Contents
9
+ **[notification-handler](notification-handler):** Create and modify your notifications through a simple API.
10
10
 
11
- * [Installation](#installation)
12
- * [Usage](#usage)
13
- * [`Notification` API](#notification-api)
14
- * [`notification_target`](#notification_target)
15
- * [`notification_object`](#notification_object)
16
- * [Groups](#groups)
17
- * [Defining a group](#defining-a-group)
18
- * [Using a group](#using-a-group)
19
- * [Caching](#caching)
20
- * [Configuration](#configuration)
21
- * [To Do](#to-do)
22
- * [Contributing](#contributing)
23
- * [Semantic versioning](#semantic-versioning)
11
+ **[notification-renderer](notification-renderer):** Render your notifications in various contexts.
24
12
 
25
- ---
13
+ **[notification-pusher](notification-pusher):** Deliver your notifications to various services, including [Email](notification-pusher/notification-pusher-actionmailer) and [OneSignal](notification-pusher/notification-pusher-onesignal).
26
14
 
27
- ## Installation
28
-
29
- NotificationHandler works with Rails 5 onwards. You can add it to your `Gemfile` with:
30
-
31
- ```ruby
32
- gem 'notification-handler'
33
- ```
34
-
35
- And then execute:
36
-
37
- $ bundle
38
-
39
- Or install it yourself as:
40
-
41
- $ gem install notification-handler
42
-
43
- Now run the generator:
44
-
45
- $ rails g notification_handler:install
46
-
47
- To wrap things up, migrate the changes to your database:
48
-
49
- $ rails db:migrate
50
-
51
- ---
52
-
53
- ## Usage
54
-
55
- ### `Notification` API
56
-
57
- You can use all the ActiveRecord methods you know and love on your `Notification` class. So creating a new notification is dead simple:
58
-
59
- ```ruby
60
- notification = Notification.new
61
- ```
62
-
63
- Every `Notification` object has a `target` record. This target record is the object, that this notification belongs to (or targets). Usually it's a user, but it can be a record of any class:
64
-
65
- ```ruby
66
- notification.target = User.first
67
- ```
68
-
69
- To store information in your `Notification` record you can use the `metadata` attribute that gets serialized as a `Hash`:
70
-
71
- ```ruby
72
- notification.metadata = {
73
- title: 'My first notification',
74
- content: "It looks great, doesn't it?"
75
- }
76
- ```
77
-
78
- Another form of adding information is by associating an object to the notification. This can be a record of any class you like:
79
-
80
- ```ruby
81
- notification.object = Recipe.first
82
- ```
83
-
84
- The `read` attribute determines whether a notification has been seen or not:
85
-
86
- ```ruby
87
- notification.read = true
88
- notification.read? # true
89
- notification.unread? # false
90
- ```
91
-
92
- You can use scopes to filter for read or unread notifications:
93
-
94
- ```ruby
95
- # Return all read notifications
96
- Notification.read
97
-
98
- # Return all unread notifications
99
- Notification.unread
100
-
101
- # Number of unread notifications
102
- Notification.unread.count
103
- ```
104
-
105
- ### `notification_target`
106
-
107
- To use records of an ActiveRecord class as notification targets, add the following to your class:
108
-
109
- ```ruby
110
- class User < ApplicationRecord
111
- notification_target
112
- end
113
- ```
114
-
115
- Now belonging notifications are easy to access:
116
-
117
- ```ruby
118
- notifications = User.first.notifications
119
- ```
120
-
121
- You can create a notification from a `target`:
122
-
123
- ```ruby
124
- User.first.notify(object: Recipe.first)
125
- ```
126
-
127
- ...
128
-
129
- ### `notification_object`
130
-
131
- When using records of an ActiveRecord class as notification objects, add this to your class:
15
+ **[notification-settings](notification-settings):** Integrates with your authentication solution to craft a personalized user notification platform.
132
16
 
133
- ```ruby
134
- class Recipe < ApplicationRecord
135
- notification_object
136
- end
137
- ```
138
-
139
- Now associated notifications are easy to access:
140
-
141
- ```ruby
142
- notifications = Recipe.first.belonging_notifications
143
- ```
144
-
145
- ...
146
-
147
- ### Groups
17
+ You may just use the components you actually need, or instead use this gem to bundle everything for a complete notification solution.
148
18
 
149
- Groups are a powerful way to bulk-create notifications for multiple objects that don't necessarily have a common class.
150
-
151
- #### Defining a group
19
+ ## Installation
152
20
 
153
- You define groups in your `NotificationHandler` configuration:
21
+ You can add notifications-rails to your `Gemfile` with:
154
22
 
155
23
  ```ruby
156
- NotificationHandler.configure do |config|
157
- config.define_group :subscribers, -> { User.where(subscriber: true) }
158
- end
24
+ gem 'notifications-rails'
159
25
  ```
160
26
 
161
- When creating a notification for the group `:subscribers`, one notification will be added for every target that fulfills this scope: `User.where(subscriber: true)`. You can also target objects from different classes:
27
+ And then run:
162
28
 
163
- ```ruby
164
- NotificationHandler.configure do |config|
165
- config.define_group :subscribers, -> { User.where(subscriber: true) + Admin.all }
166
- config.define_group :company_members, lambda { |company_id|
167
- User.with_role(:member, Company.find(company_id)
168
- }
169
- end
170
- ```
29
+ $ bundle install
171
30
 
172
- The only requirement is that the result of evaluating the proc be Enumerable.
31
+ Or install it yourself as:
173
32
 
174
- #### Using a group
33
+ $ gem install notifications-rails
175
34
 
176
- Bulk-creation of notifications for a certain group is fairly simple:
35
+ If you always want to be up to date fetch the latest from GitHub in your `Gemfile`:
177
36
 
178
37
  ```ruby
179
- notification = Notification.create(object: Recipe.first, group: :subscribers)
180
- notification = Notification.create(object: Recipe.first, group: :company_members, group_args: 4)
38
+ gem 'notifications-rails', github: 'jonhue/notifications-rails'
181
39
  ```
182
40
 
183
- **Note:** You are not able to set the `target` attribute when a `group` has been specified.
41
+ ## Usage
184
42
 
185
- ### Caching
43
+ Details on usage are provided in the [documentation](#philosophy) of the specific modules.
186
44
 
187
- You can cache the amount of unread and read notifications for notification targets by settings the [`cache`](#configuration) configuration option to `true`.
45
+ ## Development
188
46
 
189
- Then add the following columns to the database tables of ActiveRecord classes acting as notification targets:
47
+ To start development you first have to fork this repository and locally clone your fork.
190
48
 
191
- ```ruby
192
- add_column :user, :read_notification_count, :integer
193
- add_column :user, :unread_notification_count, :integer
194
- ```
49
+ Install the projects dependencies by running:
195
50
 
196
- ---
51
+ $ bundle install
197
52
 
198
- ## Configuration
53
+ ### Testing
199
54
 
200
- You can configure NotificationHandler by passing a block to `configure`. This can be done in `config/initializers/notification-handler.rb`:
55
+ Tests are written with RSpec. Integration tests are located in `/spec`, unit tests can be found in `<module>/spec`.
201
56
 
202
- ```ruby
203
- NotificationHandler.configure do |config|
204
- config.cache = true
205
- end
206
- ```
57
+ To run all tests:
207
58
 
208
- **`cache`** Cache amount of unread and read notifications for notification targets. Takes a boolean. Defaults to `false`.
59
+ $ ./rspec
209
60
 
210
- ---
61
+ To run RuboCop:
211
62
 
212
- ## To Do
63
+ $ bundle exec rubocop
213
64
 
214
- We use [GitHub projects](https://github.com/jonhue/notifications-rails/projects/2) to coordinate the work on this project.
65
+ You can find all commands run by the CI workflow in `.github/workflows/ci.yml`.
215
66
 
216
- To propose your ideas, initiate the discussion by adding a [new issue](https://github.com/jonhue/notifications-rails/issues/new).
67
+ ## Contributing
217
68
 
218
- ---
69
+ We warmly welcome everyone who is intersted in contributing. Please reference our [contributing guidelines](CONTRIBUTING.md) and our [Code of Conduct](CODE_OF_CONDUCT.md).
219
70
 
220
- ## Contributing
71
+ ## Releases
221
72
 
222
- We hope that you will consider contributing to NotificationHandler. Please read this short overview for some information about how to get started:
73
+ [Here](https://github.com/jonhue/notifications-rails/releases) you can find details on all past releases. Unreleased breaking changes that are on the current master can be found [here](CHANGELOG.md).
223
74
 
224
- [Learn more about contributing to this repository](https://github.com/jonhue/notifications-rails/blob/master/CONTRIBUTING.md), [Code of Conduct](https://github.com/jonhue/notifications-rails/blob/master/CODE_OF_CONDUCT.md)
75
+ notifications-rails follows Semantic Versioning 2.0 as defined at http://semver.org. Reference our [security policy](SECURITY.md).
225
76
 
226
- ### Semantic Versioning
77
+ ### Publishing
227
78
 
228
- NotificationHandler follows Semantic Versioning 2.0 as defined at http://semver.org.
79
+ 1. Review breaking changes and deprecations in `CHANGELOG.md`.
80
+ 1. Change the gem version in `VERSION`.
81
+ 1. Reset `CHANGELOG.md`.
82
+ 1. Create a pull request to merge the changes into `master`.
83
+ 1. After the pull request was merged, create a new release listing the breaking changes and commits on `master` since the last release.
84
+ 1. The release workflow will publish the gems to RubyGems.
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'notification-handler'
4
+ require 'notification-renderer'
5
+ require 'notification-pusher'
6
+ require 'notification-settings'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: notification-handler
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonas Hübotter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-04 00:00:00.000000000 Z
11
+ date: 2022-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -151,30 +151,19 @@ dependencies:
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
153
  description: Create and modify your notifications through a simple API.
154
- email: me@jonhue.me
154
+ email: jonas.huebotter@gmail.com
155
155
  executables: []
156
156
  extensions: []
157
157
  extra_rdoc_files: []
158
158
  files:
159
159
  - LICENSE
160
160
  - README.md
161
- - app/models/notification_handler/notification.rb
162
- - lib/generators/notification_handler/install_generator.rb
163
- - lib/generators/templates/install/initializer.rb
164
- - lib/generators/templates/install/notification_model.rb
165
- - lib/generators/templates/install/notifications_migration.rb.erb
166
- - lib/notification-handler.rb
167
- - lib/notification_handler/configuration.rb
168
- - lib/notification_handler/engine.rb
169
- - lib/notification_handler/group.rb
170
- - lib/notification_handler/notification_lib.rb
171
- - lib/notification_handler/notification_scopes.rb
172
- - lib/notification_handler/object.rb
173
- - lib/notification_handler/target.rb
161
+ - lib/notifications-rails.rb
174
162
  homepage: https://github.com/jonhue/notifications-rails/tree/master/notification-handler
175
163
  licenses:
176
164
  - MIT
177
- metadata: {}
165
+ metadata:
166
+ github_repo: ssh://github.com/jonhue/notifications-rails
178
167
  post_install_message:
179
168
  rdoc_options: []
180
169
  require_paths:
@@ -183,14 +172,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
183
172
  requirements:
184
173
  - - ">="
185
174
  - !ruby/object:Gem::Version
186
- version: 2.2.2
175
+ version: '2.7'
187
176
  required_rubygems_version: !ruby/object:Gem::Requirement
188
177
  requirements:
189
178
  - - ">="
190
179
  - !ruby/object:Gem::Version
191
180
  version: '0'
192
181
  requirements: []
193
- rubygems_version: 3.0.3
182
+ rubygems_version: 3.3.7
194
183
  signing_key:
195
184
  specification_version: 4
196
185
  summary: Create and modify your notifications through a simple API
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module NotificationHandler
4
- class Notification < ApplicationRecord
5
- include NotificationHandler::NotificationLib
6
- include NotificationHandler::NotificationScopes
7
- end
8
- end
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rails/generators'
4
- require 'rails/generators/migration'
5
-
6
- module NotificationHandler
7
- class InstallGenerator < Rails::Generators::Base
8
- include Rails::Generators::Migration
9
-
10
- source_root(File.join(File.dirname(__FILE__), '../templates/install'))
11
- desc 'Install NotificationHandler'
12
-
13
- def self.next_migration_number(dirname)
14
- if ActiveRecord::Base.timestamped_migrations
15
- Time.now.utc.strftime('%Y%m%d%H%M%S')
16
- else
17
- format('%.3d', current_migration_number(dirname) + 1)
18
- end
19
- end
20
-
21
- def create_initializer
22
- template 'initializer.rb', 'config/initializers/notification_handler.rb'
23
- end
24
-
25
- def create_notifications_migration_file
26
- migration_template(
27
- 'notifications_migration.rb.erb',
28
- 'db/migrate/notification_handler_migration.rb',
29
- migration_version: migration_version
30
- )
31
- end
32
-
33
- def create_notification_model
34
- template 'notification_model.rb', 'app/models/notification.rb'
35
- end
36
-
37
- private
38
-
39
- def migration_version
40
- return unless Rails.version >= '5.0.0'
41
-
42
- "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
43
- end
44
- end
45
- end
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- NotificationHandler.configure do |config|
4
- # Cache amount of unread and read notifications for notification targets.
5
- # Learn more: https://github.com/jonhue/notifications-rails/tree/master/notification-handler#caching
6
- # config.cache = false
7
-
8
- # Groups are a powerful way to bulk-create notifications for multiple objects
9
- # that don't necessarily have a common class.
10
- # Learn more: https://github.com/jonhue/notifications-rails/tree/master/notification-handler#groups
11
- # config.define_group :subscribers, -> { User.where(subscriber: true) }
12
- end
@@ -1,4 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Notification < NotificationHandler::Notification
4
- end
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class NotificationHandlerMigration < ActiveRecord::Migration<%= migration_version %>
4
- def change
5
- create_table :notifications do |t|
6
- t.references :target, polymorphic: true, index: true
7
- t.references :object, polymorphic: true, index: true
8
-
9
- t.boolean :read, default: false, null: false, index: true
10
-
11
- t.text :metadata
12
-
13
- t.timestamps
14
- end
15
- end
16
- end
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module NotificationHandler
4
- require_relative 'notification_handler/configuration'
5
-
6
- require_relative 'notification_handler/engine'
7
-
8
- autoload :Group, 'notification_handler/group'
9
-
10
- autoload :Target, 'notification_handler/target'
11
- autoload :Object, 'notification_handler/object'
12
- autoload :NotificationLib, 'notification_handler/notification_lib'
13
- autoload :NotificationScopes, 'notification_handler/notification_scopes'
14
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'group'
4
-
5
- module NotificationHandler
6
- class << self
7
- attr_writer :configuration
8
-
9
- def configuration
10
- @configuration ||= Configuration.new
11
- end
12
- end
13
-
14
- def self.configure
15
- yield configuration
16
- end
17
-
18
- class Configuration
19
- attr_accessor :groups
20
- attr_accessor :cache
21
-
22
- def initialize
23
- @groups = {}
24
- @cache = false
25
- end
26
-
27
- def define_group(name, target_scope)
28
- groups[name.to_sym] = ::NotificationHandler::Group.new(target_scope)
29
- end
30
- end
31
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rails/engine'
4
- require 'active_record'
5
-
6
- module NotificationHandler
7
- class Engine < ::Rails::Engine
8
- initializer 'notification-handler.active_record' do
9
- ActiveSupport.on_load :active_record do
10
- include NotificationHandler::Target
11
- include NotificationHandler::Object
12
- end
13
- end
14
- end
15
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module NotificationHandler
4
- class Group
5
- attr_reader :target_scope
6
-
7
- def initialize(target_scope)
8
- @target_scope = target_scope
9
- end
10
-
11
- def self.find_by_name(name)
12
- NotificationHandler.configuration.groups[name]
13
- end
14
-
15
- def self.find_by_name!(name)
16
- find_by_name(name) ||
17
- raise(ArgumentError,
18
- "Could not find a registered group for #{name}. " \
19
- "Make sure you register it with config.define_group :#{name}")
20
- end
21
- end
22
- end
@@ -1,68 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'active_support'
4
-
5
- module NotificationHandler
6
- module NotificationLib
7
- extend ActiveSupport::Concern
8
-
9
- included do
10
- self.inheritance_column = :_type_disabled
11
-
12
- before_validation :create_for_group
13
- after_commit :cache
14
-
15
- serialize :metadata, Hash
16
- attr_accessor :group
17
- attr_accessor :group_args
18
-
19
- belongs_to :target, polymorphic: true
20
- belongs_to :object, polymorphic: true, optional: true
21
-
22
- include NotificationHandler::NotificationLib::InstanceMethods
23
-
24
- if defined?(NotificationRenderer)
25
- include NotificationRenderer::NotificationLib
26
- end
27
- if defined?(NotificationPusher)
28
- include NotificationPusher::NotificationLib
29
- end
30
- if defined?(NotificationSettings)
31
- include NotificationSettings::NotificationLib
32
- end
33
- end
34
-
35
- module InstanceMethods
36
- def read?
37
- read
38
- end
39
-
40
- def unread?
41
- !read
42
- end
43
-
44
- private
45
-
46
- def create_for_group
47
- return if group.nil?
48
-
49
- target_scope = NotificationHandler::Group.find_by_name!(group)
50
- .target_scope
51
- target_scope.call(*group_args)&.each_with_index do |target, index|
52
- notification = index.zero? ? self : dup
53
- notification.target = target
54
- notification.group = nil
55
- notification.save!
56
- end
57
- end
58
-
59
- def cache
60
- return unless read_changed?
61
-
62
- target.read_notification_count = target.notifications.read.count
63
- target.unread_notification_count = target.notifications.unread.count
64
- target.save!
65
- end
66
- end
67
- end
68
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'active_support'
4
-
5
- module NotificationHandler
6
- module NotificationScopes
7
- extend ActiveSupport::Concern
8
-
9
- included do
10
- scope :read, -> { where(read: true) }
11
- scope :unread, -> { where(read: false) }
12
-
13
- if defined?(NotificationRenderer)
14
- include NotificationRenderer::NotificationScopes
15
- end
16
- if defined?(NotificationSettings)
17
- include NotificationSettings::NotificationScopes
18
- end
19
- end
20
- end
21
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module NotificationHandler
4
- module Object
5
- def self.included(base)
6
- base.extend(ClassMethods)
7
- end
8
-
9
- module ClassMethods
10
- def notification_object
11
- has_many :belonging_notifications,
12
- as: :object, class_name: 'Notification', dependent: :destroy
13
- include NotificationHandler::Object::InstanceMethods
14
-
15
- return unless defined?(NotificationSettings)
16
-
17
- include NotificationSettings::Subscribable
18
- end
19
- end
20
-
21
- module InstanceMethods
22
- # ...
23
- end
24
- end
25
- end
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module NotificationHandler
4
- module Target
5
- def self.included(base)
6
- base.extend(ClassMethods)
7
- end
8
-
9
- module ClassMethods
10
- def notification_target
11
- has_many :notifications, as: :target, dependent: :destroy
12
- include NotificationHandler::Target::InstanceMethods
13
-
14
- include NotificationSettings::Target if defined?(NotificationSettings)
15
- return unless defined?(NotificationSettings)
16
-
17
- include NotificationSettings::Subscriber
18
- end
19
- end
20
-
21
- module InstanceMethods
22
- def notify(options = {})
23
- notifications.create(options)
24
- end
25
- end
26
- end
27
- end