activity_notification 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +56 -0
  4. data/.rspec +3 -0
  5. data/.travis.yml +28 -0
  6. data/Gemfile +8 -0
  7. data/Gemfile.lock +174 -0
  8. data/MIT-LICENSE +20 -0
  9. data/README.md +437 -0
  10. data/Rakefile +19 -0
  11. data/activity_notification.gemspec +33 -0
  12. data/app/controllers/activity_notification/notifications_controller.rb +119 -0
  13. data/app/controllers/activity_notification/notifications_with_devise_controller.rb +29 -0
  14. data/app/mailers/activity_notification/mailer.rb +13 -0
  15. data/app/views/activity_notification/mailer/default/default.html.erb +7 -0
  16. data/app/views/activity_notification/notifications/default/_default.html.erb +36 -0
  17. data/app/views/activity_notification/notifications/default/_index.html.erb +9 -0
  18. data/app/views/activity_notification/notifications/default/destroy.js.erb +2 -0
  19. data/app/views/activity_notification/notifications/default/index.html.erb +17 -0
  20. data/app/views/activity_notification/notifications/default/open.js.erb +2 -0
  21. data/app/views/activity_notification/notifications/default/open_all.js.erb +2 -0
  22. data/app/views/activity_notification/notifications/default/show.html.erb +2 -0
  23. data/config/locales/en.yml +8 -0
  24. data/lib/activity_notification.rb +52 -0
  25. data/lib/activity_notification/apis/notification_api.rb +147 -0
  26. data/lib/activity_notification/common.rb +86 -0
  27. data/lib/activity_notification/config.rb +23 -0
  28. data/lib/activity_notification/controllers/store_controller.rb +30 -0
  29. data/lib/activity_notification/helpers/polymorphic_helpers.rb +32 -0
  30. data/lib/activity_notification/helpers/view_helpers.rb +108 -0
  31. data/lib/activity_notification/mailers/helpers.rb +97 -0
  32. data/lib/activity_notification/models/notifiable.rb +136 -0
  33. data/lib/activity_notification/models/notification.rb +50 -0
  34. data/lib/activity_notification/models/notifier.rb +11 -0
  35. data/lib/activity_notification/models/target.rb +104 -0
  36. data/lib/activity_notification/rails.rb +6 -0
  37. data/lib/activity_notification/rails/routes.rb +105 -0
  38. data/lib/activity_notification/renderable.rb +142 -0
  39. data/lib/activity_notification/roles/acts_as_notifiable.rb +37 -0
  40. data/lib/activity_notification/roles/acts_as_target.rb +30 -0
  41. data/lib/activity_notification/version.rb +3 -0
  42. data/lib/generators/activity_notification/controllers_generator.rb +44 -0
  43. data/lib/generators/activity_notification/install_generator.rb +45 -0
  44. data/lib/generators/activity_notification/migration/migration_generator.rb +17 -0
  45. data/lib/generators/activity_notification/notification/notification_generator.rb +17 -0
  46. data/lib/generators/activity_notification/views_generator.rb +44 -0
  47. data/lib/generators/templates/README +53 -0
  48. data/lib/generators/templates/active_record/migration.rb +18 -0
  49. data/lib/generators/templates/activity_notification.rb +18 -0
  50. data/lib/generators/templates/controllers/README +13 -0
  51. data/lib/generators/templates/controllers/notifications_controller.rb +66 -0
  52. data/lib/generators/templates/controllers/notifications_with_devise_controller.rb +74 -0
  53. data/lib/generators/templates/notification/notification.rb +3 -0
  54. data/lib/tasks/activity_notification_tasks.rake +4 -0
  55. data/spec/concerns/notification_api_spec.rb +531 -0
  56. data/spec/factories/articles.rb +5 -0
  57. data/spec/factories/comments.rb +6 -0
  58. data/spec/factories/notifications.rb +7 -0
  59. data/spec/factories/users.rb +5 -0
  60. data/spec/models/notification_spec.rb +259 -0
  61. data/spec/rails_app/Rakefile +6 -0
  62. data/spec/rails_app/app/controllers/application_controller.rb +5 -0
  63. data/spec/rails_app/app/controllers/concerns/.keep +0 -0
  64. data/spec/rails_app/app/helpers/application_helper.rb +2 -0
  65. data/spec/rails_app/app/mailers/.keep +0 -0
  66. data/spec/rails_app/app/models/.keep +0 -0
  67. data/spec/rails_app/app/models/article.rb +12 -0
  68. data/spec/rails_app/app/models/comment.rb +18 -0
  69. data/spec/rails_app/app/models/concerns/.keep +0 -0
  70. data/spec/rails_app/app/models/user.rb +8 -0
  71. data/spec/rails_app/app/views/layouts/application.html.erb +14 -0
  72. data/spec/rails_app/bin/bundle +3 -0
  73. data/spec/rails_app/bin/rails +4 -0
  74. data/spec/rails_app/bin/rake +4 -0
  75. data/spec/rails_app/bin/setup +29 -0
  76. data/spec/rails_app/config.ru +4 -0
  77. data/spec/rails_app/config/application.rb +20 -0
  78. data/spec/rails_app/config/boot.rb +5 -0
  79. data/spec/rails_app/config/database.yml +25 -0
  80. data/spec/rails_app/config/environment.rb +12 -0
  81. data/spec/rails_app/config/environments/development.rb +44 -0
  82. data/spec/rails_app/config/environments/production.rb +79 -0
  83. data/spec/rails_app/config/environments/test.rb +45 -0
  84. data/spec/rails_app/config/initializers/activity_notification.rb +18 -0
  85. data/spec/rails_app/config/initializers/assets.rb +11 -0
  86. data/spec/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  87. data/spec/rails_app/config/initializers/cookies_serializer.rb +3 -0
  88. data/spec/rails_app/config/initializers/devise.rb +274 -0
  89. data/spec/rails_app/config/initializers/filter_parameter_logging.rb +4 -0
  90. data/spec/rails_app/config/initializers/inflections.rb +16 -0
  91. data/spec/rails_app/config/initializers/mime_types.rb +4 -0
  92. data/spec/rails_app/config/initializers/session_store.rb +3 -0
  93. data/spec/rails_app/config/initializers/wrap_parameters.rb +14 -0
  94. data/spec/rails_app/config/routes.rb +5 -0
  95. data/spec/rails_app/config/secrets.yml +22 -0
  96. data/spec/rails_app/db/migrate/20160715050420_create_notifications.rb +18 -0
  97. data/spec/rails_app/db/migrate/20160715050433_create_test_tables.rb +36 -0
  98. data/spec/rails_app/db/schema.rb +73 -0
  99. data/spec/rails_app/public/404.html +67 -0
  100. data/spec/rails_app/public/422.html +67 -0
  101. data/spec/rails_app/public/500.html +66 -0
  102. data/spec/rails_app/public/favicon.ico +0 -0
  103. data/spec/spec_helper.rb +34 -0
  104. metadata +309 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 21216d2e8404074f8d41386c1efd69e5807fe1a0
4
+ data.tar.gz: a7f47206261d82ab891c26b11a75d2651ac181ad
5
+ SHA512:
6
+ metadata.gz: 8a17fcd05b829941cf7c0ab09d384d13ef18946aaee3df1e21e9798a9dc170fc4e905b36feeaa33b86785f26830eccc8950105162c2d1ef5f56ec84777e74ded
7
+ data.tar.gz: 3763b40e578293462beb8a92227cd18e0e907ceae53c9bba5b3981d07a7c2ecb4a065dd4e11bd820b38adfd52f58b42cb965b5fe8223a9111c1ec188b0cf6439
data/.coveralls.yml ADDED
@@ -0,0 +1 @@
1
+ service_name: travis-ci
data/.gitignore ADDED
@@ -0,0 +1,56 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /spec/rails_app/log/*
10
+ /spec/rails_app/tmp/*
11
+ /test/tmp/
12
+ /test/version_tmp/
13
+ /tmp/
14
+ /log/
15
+ *~
16
+ *.sqlite3
17
+ .project
18
+
19
+ # Used by dotenv library to load environment variables.
20
+ # .env
21
+
22
+ ## Specific to RubyMotion:
23
+ .dat*
24
+ .repl_history
25
+ build/
26
+ *.bridgesupport
27
+ build-iPhoneOS/
28
+ build-iPhoneSimulator/
29
+
30
+ ## Specific to RubyMotion (use of CocoaPods):
31
+ #
32
+ # We recommend against adding the Pods directory to your .gitignore. However
33
+ # you should judge for yourself, the pros and cons are mentioned at:
34
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
35
+ #
36
+ # vendor/Pods/
37
+
38
+ ## Documentation cache and generated files:
39
+ /.yardoc/
40
+ /_yardoc/
41
+ /doc/
42
+ /rdoc/
43
+
44
+ ## Environment normalization:
45
+ /.bundle/
46
+ /vendor/bundle
47
+ /lib/bundler/man/
48
+
49
+ # for a library or gem, you might want to ignore these files since the code is
50
+ # intended to run in multiple environments; otherwise, check them in:
51
+ # Gemfile.lock
52
+ # .ruby-version
53
+ # .ruby-gemset
54
+
55
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
56
+ .rvmrc
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --format documentation
data/.travis.yml ADDED
@@ -0,0 +1,28 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - 2.1.9
5
+ - 2.2.5
6
+ - 2.3.1
7
+ - ruby-head
8
+
9
+ gemfile:
10
+ - Gemfile
11
+
12
+ matrix:
13
+ allow_failures:
14
+ - rvm: ruby-head
15
+ fast_finish: true
16
+
17
+ sudo: false
18
+
19
+ cache: bundler
20
+
21
+ before_install: "rm ${BUNDLE_GEMFILE}.lock"
22
+
23
+ before_script: "bundle update"
24
+
25
+ script: bundle exec rspec
26
+
27
+ notifications:
28
+ email: true
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem 'timecop'
7
+ gem 'coveralls', require: false
8
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,174 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ activity_notification (0.0.8)
5
+ activerecord (>= 3.0)
6
+ i18n (>= 0.5.0)
7
+ rails (~> 4.2)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ actionmailer (4.2.7)
13
+ actionpack (= 4.2.7)
14
+ actionview (= 4.2.7)
15
+ activejob (= 4.2.7)
16
+ mail (~> 2.5, >= 2.5.4)
17
+ rails-dom-testing (~> 1.0, >= 1.0.5)
18
+ actionpack (4.2.7)
19
+ actionview (= 4.2.7)
20
+ activesupport (= 4.2.7)
21
+ rack (~> 1.6)
22
+ rack-test (~> 0.6.2)
23
+ rails-dom-testing (~> 1.0, >= 1.0.5)
24
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
25
+ actionview (4.2.7)
26
+ activesupport (= 4.2.7)
27
+ builder (~> 3.1)
28
+ erubis (~> 2.7.0)
29
+ rails-dom-testing (~> 1.0, >= 1.0.5)
30
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
31
+ activejob (4.2.7)
32
+ activesupport (= 4.2.7)
33
+ globalid (>= 0.3.0)
34
+ activemodel (4.2.7)
35
+ activesupport (= 4.2.7)
36
+ builder (~> 3.1)
37
+ activerecord (4.2.7)
38
+ activemodel (= 4.2.7)
39
+ activesupport (= 4.2.7)
40
+ arel (~> 6.0)
41
+ activesupport (4.2.7)
42
+ i18n (~> 0.7)
43
+ json (~> 1.7, >= 1.7.7)
44
+ minitest (~> 5.1)
45
+ thread_safe (~> 0.3, >= 0.3.4)
46
+ tzinfo (~> 1.1)
47
+ arel (6.0.3)
48
+ bcrypt (3.1.11)
49
+ builder (3.2.2)
50
+ concurrent-ruby (1.0.2)
51
+ coveralls (0.8.14)
52
+ json (>= 1.8, < 3)
53
+ simplecov (~> 0.12.0)
54
+ term-ansicolor (~> 1.3)
55
+ thor (~> 0.19.1)
56
+ tins (~> 1.6.0)
57
+ devise (4.2.0)
58
+ bcrypt (~> 3.0)
59
+ orm_adapter (~> 0.1)
60
+ railties (>= 4.1.0, < 5.1)
61
+ responders
62
+ warden (~> 1.2.3)
63
+ diff-lcs (1.2.5)
64
+ docile (1.1.5)
65
+ erubis (2.7.0)
66
+ factory_girl (4.7.0)
67
+ activesupport (>= 3.0.0)
68
+ factory_girl_rails (4.7.0)
69
+ factory_girl (~> 4.7.0)
70
+ railties (>= 3.0.0)
71
+ globalid (0.3.6)
72
+ activesupport (>= 4.1.0)
73
+ i18n (0.7.0)
74
+ json (1.8.3)
75
+ loofah (2.0.3)
76
+ nokogiri (>= 1.5.9)
77
+ mail (2.6.4)
78
+ mime-types (>= 1.16, < 4)
79
+ mime-types (3.1)
80
+ mime-types-data (~> 3.2015)
81
+ mime-types-data (3.2016.0521)
82
+ mini_portile2 (2.1.0)
83
+ minitest (5.9.0)
84
+ nokogiri (1.6.8)
85
+ mini_portile2 (~> 2.1.0)
86
+ pkg-config (~> 1.1.7)
87
+ orm_adapter (0.5.0)
88
+ pkg-config (1.1.7)
89
+ rack (1.6.4)
90
+ rack-test (0.6.3)
91
+ rack (>= 1.0)
92
+ rails (4.2.7)
93
+ actionmailer (= 4.2.7)
94
+ actionpack (= 4.2.7)
95
+ actionview (= 4.2.7)
96
+ activejob (= 4.2.7)
97
+ activemodel (= 4.2.7)
98
+ activerecord (= 4.2.7)
99
+ activesupport (= 4.2.7)
100
+ bundler (>= 1.3.0, < 2.0)
101
+ railties (= 4.2.7)
102
+ sprockets-rails
103
+ rails-deprecated_sanitizer (1.0.3)
104
+ activesupport (>= 4.2.0.alpha)
105
+ rails-dom-testing (1.0.7)
106
+ activesupport (>= 4.2.0.beta, < 5.0)
107
+ nokogiri (~> 1.6.0)
108
+ rails-deprecated_sanitizer (>= 1.0.1)
109
+ rails-html-sanitizer (1.0.3)
110
+ loofah (~> 2.0)
111
+ railties (4.2.7)
112
+ actionpack (= 4.2.7)
113
+ activesupport (= 4.2.7)
114
+ rake (>= 0.8.7)
115
+ thor (>= 0.18.1, < 2.0)
116
+ rake (11.2.2)
117
+ responders (2.2.0)
118
+ railties (>= 4.2.0, < 5.1)
119
+ rspec-core (3.5.1)
120
+ rspec-support (~> 3.5.0)
121
+ rspec-expectations (3.5.0)
122
+ diff-lcs (>= 1.2.0, < 2.0)
123
+ rspec-support (~> 3.5.0)
124
+ rspec-mocks (3.5.0)
125
+ diff-lcs (>= 1.2.0, < 2.0)
126
+ rspec-support (~> 3.5.0)
127
+ rspec-rails (3.5.1)
128
+ actionpack (>= 3.0)
129
+ activesupport (>= 3.0)
130
+ railties (>= 3.0)
131
+ rspec-core (~> 3.5.0)
132
+ rspec-expectations (~> 3.5.0)
133
+ rspec-mocks (~> 3.5.0)
134
+ rspec-support (~> 3.5.0)
135
+ rspec-support (3.5.0)
136
+ simplecov (0.12.0)
137
+ docile (~> 1.1.0)
138
+ json (>= 1.8, < 3)
139
+ simplecov-html (~> 0.10.0)
140
+ simplecov-html (0.10.0)
141
+ sprockets (3.6.3)
142
+ concurrent-ruby (~> 1.0)
143
+ rack (> 1, < 3)
144
+ sprockets-rails (3.1.1)
145
+ actionpack (>= 4.0)
146
+ activesupport (>= 4.0)
147
+ sprockets (>= 3.0.0)
148
+ sqlite3 (1.3.11)
149
+ term-ansicolor (1.3.2)
150
+ tins (~> 1.0)
151
+ thor (0.19.1)
152
+ thread_safe (0.3.5)
153
+ timecop (0.8.1)
154
+ tins (1.6.0)
155
+ tzinfo (1.2.2)
156
+ thread_safe (~> 0.1)
157
+ warden (1.2.6)
158
+ rack (>= 1.0)
159
+
160
+ PLATFORMS
161
+ ruby
162
+
163
+ DEPENDENCIES
164
+ activity_notification!
165
+ coveralls
166
+ devise (~> 4.2.0)
167
+ factory_girl_rails (~> 4.7.0)
168
+ rspec-rails (~> 3.5.1)
169
+ simplecov (~> 0.12.0)
170
+ sqlite3 (~> 1.3.11)
171
+ timecop
172
+
173
+ BUNDLED WITH
174
+ 1.12.5
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2016 Shota Yamazaki
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,437 @@
1
+ # ActivityNotification
2
+
3
+ [![Build Status](https://travis-ci.org/simukappu/activity_notification.svg?branch=master)](https://travis-ci.org/simukappu/activity_notification)
4
+ [![Coverage Status](https://coveralls.io/repos/github/simukappu/activity_notification/badge.svg?branch=master)](https://coveralls.io/github/simukappu/activity_notification?branch=master)
5
+ [![Code Climate](https://codeclimate.com/github/simukappu/activity_notification/badges/gpa.svg)](https://codeclimate.com/github/simukappu/activity_notification)
6
+ [![Gem Version](https://badge.fury.io/rb/activity_notification.svg)](https://badge.fury.io/rb/activity_notification)
7
+ [![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](MIT-LICENSE)
8
+
9
+ `activity_notification` provides integrated user activity notifications for Rails. You can easily use it to configure multiple notification targets and make activity notifications with notifiable models, like adding comments, responding etc.
10
+
11
+ Currently, `activity_notification` is only supported with ActiveRecord ORM in Rails 4.
12
+
13
+
14
+ ## Table of contents
15
+
16
+ 1. [About](#about)
17
+ 2. [Setup](#setup)
18
+ 1. [Gem installation](#gem-installation)
19
+ 2. [Database setup](#database-setup)
20
+ 3. [Configuring models](#configuring-models)
21
+ 1. [Configuring target model](#configuring-target-model)
22
+ 2. [Configuring notifiable model](#configuring-notifiable-model)
23
+ 4. [Configuring views](#configuring-views)
24
+ 5. [Configuring controllers](#configuring-controllers)
25
+ 6. [Configuring routes](#configuring-routes)
26
+ 7. [Creating notifications](#creating-notifications)
27
+ 8. [Displaying notifications](#displaying-notifications)
28
+ 1. [Preparing target notifications](#preparing-target-notifications)
29
+ 2. [Rendering notifications](#rendering-notifications)
30
+ 3. [Notification views](#notification-views)
31
+ 4. [i18n for notifications](#i18n-for-notifications)
32
+ 5. [Grouping notifications](#grouping-notifications)
33
+ 9. [Configuring email notification](#configuring-email-notification)
34
+ 1. [Setup mailer](#setup-mailer)
35
+ 2. [Email templates](#email-templates)
36
+ 3. [i18n for email](#i18n-for-email)
37
+ 4. [Testing](#testing)
38
+ 5. [Documentation](#documentation)
39
+ 6. **[Common examples](#common-examples)**
40
+
41
+ ## About
42
+
43
+ `activity_notification` provides following functions:
44
+ * Notification API (creating notifications, query for notifications and managing notification parameters)
45
+ * Notification controllers (managing open/unopen of notifications, link to notifiable activity page)
46
+ * Notification views (presentation of notifications)
47
+ * Notification grouping (grouping like `"Tom and other 7 people posted comments to this article"`)
48
+ * Email notification
49
+ * Integration with [Devise](https://github.com/plataformatec/devise) authentication
50
+
51
+ `activity_notification` deeply uses [PublicActivity](https://github.com/pokonski/public_activity) as reference in presentation layer.
52
+
53
+ ## Setup
54
+
55
+ ### Gem installation
56
+
57
+ You can install `activity_notification` as you would any other gem:
58
+
59
+ ```console
60
+ $ gem install activity_notification
61
+ ```
62
+ or in your Gemfile:
63
+
64
+ ```ruby
65
+ gem 'activity_notification'
66
+ ```
67
+
68
+ After you install `activity_notification` and add it to your Gemfile, you need to run the generator:
69
+
70
+ ```console
71
+ $ rails generate activity_notification:install
72
+ ```
73
+
74
+ The generator will install an initializer which describes all configuration options of `activity_notification`.
75
+ It also generates a i18n based translation file which we can configure the presentation of notifications.
76
+
77
+ ### Database setup
78
+
79
+ Currently `activity_notification` is only supported with ActiveRecord.
80
+ Create migration for notifications and migrate the database in your Rails project:
81
+
82
+ ```console
83
+ $ rails generate activity_notification:migration
84
+ $ rake db:migrate
85
+ ```
86
+
87
+ ### Configuring models
88
+
89
+ #### Configuring target model
90
+
91
+ Configure your target model (e.g. app/models/user.rb).
92
+ Add including statement and `acts_as_target` configuration to your target model to get notifications.
93
+
94
+ ```ruby
95
+ class User < ActiveRecord::Base
96
+ include ActivityNotification::Target
97
+ # Example using confirmed_at of Device field
98
+ # to decide whether activity_notification sends notification email to this user
99
+ acts_as_target email: :email, email_allowed: :confirmed_at
100
+ end
101
+ ```
102
+
103
+ You can override several methods in your target model (e.g. `notification_index` or `notification_email_allowed?`).
104
+
105
+ #### Configuring notifiable model
106
+
107
+ Configure your notifiable model (e.g. app/models/comment.rb).
108
+ Add including statement and `acts_as_notifiable` configuration to your notifiable model representing activity to notify.
109
+ You have to define notification targets for all notifications from this notifiable model by `:targets` option. Other configurations are options.
110
+
111
+ ```ruby
112
+ class Comment < ActiveRecord::Base
113
+ belongs_to :article
114
+ belongs_to :user
115
+
116
+ include ActivityNotification::Notifiable
117
+ # Example that ActivityNotification::Notifiable is configured with custom methods in your model as symbol
118
+ acts_as_notifiable :users,
119
+ targets: :custom_notification_users,
120
+ group: :article,
121
+ notifier: :user,
122
+ email_allowed: :custom_notification_email_to_users_allowed?,
123
+ notifiable_path: :custom_notifiable_path
124
+
125
+ def custom_notification_users(key)
126
+ User.where(id: self.article.comments.pluck(:user_id))
127
+ end
128
+
129
+ def custom_notification_email_to_users_allowed?(user, key)
130
+ true
131
+ end
132
+
133
+ def custom_notifiable_path
134
+ article_path(article)
135
+ end
136
+
137
+ end
138
+ ```
139
+
140
+ You can override several methods in your notifiable model (e.g. `notifiable_path` or `notification_email_allowed?`).
141
+
142
+ ### Configuring views
143
+
144
+ `activity_notification` provides view templates to customize your notification views. The view generater can generate default views for all targets.
145
+
146
+ ```console
147
+ $ rails generate activity_notification:views
148
+ ```
149
+
150
+ If you have multiple target models in your application, such as `User` and `Admin`, you will be able to have views based on the target like `notifications/users/index` and `notifications/admins/index`. If no view is found for the target, `activity_notification` will use the default view at `notifications/default/index`. You can also use the generator to generate views for the specified target:
151
+
152
+ ```console
153
+ $ rails generate activity_notification:views users
154
+ ```
155
+
156
+ If you would like to generate only a few sets of views, like the ones for the `notifications` (for notification views) and `mailer` (for notification email views),
157
+ you can pass a list of modules to the generator with the `-v` flag.
158
+
159
+ ```console
160
+ $ rails generate activity_notification:views -v mailer
161
+ ```
162
+
163
+ ### Configuring controllers
164
+
165
+ If the customization at the views level is not enough, you can customize each controller by following these steps:
166
+
167
+ 1. Create your custom controllers using the generator with a target:
168
+
169
+ ```console
170
+ $ rails generate activity_notification:controllers users
171
+ ```
172
+
173
+ If you specify `users` as the target, controllers will be created in `app/controllers/users/`.
174
+ And the notifications controller will look like this:
175
+
176
+ ```ruby
177
+ class Users::NotificationsController < ActivityNotification::NotificationsController
178
+ # GET /:target_type/:target_id/notifcations
179
+ # def index
180
+ # super
181
+ # end
182
+ ...
183
+ end
184
+ ```
185
+
186
+ 2. Tell the router to use this controller:
187
+
188
+ ```ruby
189
+ notify_to :users, controllers: { notifcations: 'users/notifcations' }
190
+ ```
191
+
192
+ 3. Generate views from `activity_notification/notifcations/users` to `users/notifcations/users`. Since the controller was changed, it won't use the default views located in `activity_notification/notifcations/default`.
193
+
194
+ 4. Finally, change or extend the desired controller actions.
195
+
196
+ You can completely override a controller action
197
+ ```ruby
198
+ class Users::NotificationsController < ActivityNotification::NotificationsController
199
+ # POST /:target_type/:target_id/notifcations/:id/open
200
+ def open
201
+ # custom open-notification code
202
+ end
203
+ ...
204
+ end
205
+ ```
206
+
207
+ ### Configuring routes
208
+
209
+ `activity_notification` also provides routing helper. Add notification routing to `config/routes.rb` for the target (e.g. `:users`):
210
+
211
+ ```ruby
212
+ # Simply
213
+ Rails.application.routes.draw do
214
+ notify_to :users
215
+ end
216
+
217
+ # Or integrated with devise
218
+ Rails.application.routes.draw do
219
+ notify_to :users, with_devise: :users
220
+ end
221
+ ```
222
+
223
+ ### Creating notifications
224
+
225
+ You can trigger notifications by setting all your required parameters and triggering `notify`
226
+ on the notifiable model, like this:
227
+
228
+ ```ruby
229
+ @comment.notify User key: 'article.commented_on', group: @comment.article
230
+ ```
231
+
232
+ Or, you can call public API as `ActivityNotification::Notification.notify`
233
+
234
+ ```ruby
235
+ ActivityNotification::Notification.notify User, @comment, group: @comment.article
236
+ ```
237
+
238
+ ### Displaying notifications
239
+
240
+ #### Preparing target notifications
241
+
242
+ To display notifications, you can use `notifications` association of the target model:
243
+
244
+ ```ruby
245
+ # custom_notifications_controller.rb
246
+ def index
247
+ @notifications = @target.notifications
248
+ end
249
+ ```
250
+
251
+ You can also use several scope to filter notifications. For example, `unopened_only` to filter them unopened notifications only.
252
+
253
+ ```ruby
254
+ # custom_notifications_controller.rb
255
+ def index
256
+ @notifications = @target.notifications.unopened_only
257
+ end
258
+ ```
259
+
260
+ Moreover, you can use `notification_index` or `notification_index_with_attributes` methods to automatically prepare notification index for the target.
261
+
262
+ ```ruby
263
+ # custom_notifications_controller.rb
264
+ def index
265
+ @notifications = @target.notification_index_with_attributes
266
+ end
267
+ ```
268
+
269
+ #### Rendering notifications
270
+
271
+ You can use `render_notifications` helper in your views to show the notification index:
272
+
273
+ ```erb
274
+ <%= render_notifications(@notifications) %>
275
+ ```
276
+
277
+ We can set `:target` option to specify the target type of notifications:
278
+
279
+ ```erb
280
+ <%= render_notifications(@notifications, target: :users) %>
281
+ ```
282
+
283
+ *Note*: `render_notifications` is an alias for `render_notification` and does the same.
284
+
285
+ If you want to set notification index in the common layout, such as common header, you can use `render_notifications_of` helper like this:
286
+
287
+ ```shared/_header.html.erb
288
+ <%= render_notifications_of current_user, index_content: :with_attributes %>
289
+ ```
290
+
291
+ Then, content named :notification_index will be prepared and you can use it in your partial template.
292
+
293
+ ```activity_notifications/notifications/users/_index.html.erb
294
+ ...
295
+ <%= yield :notification_index %>
296
+ ...
297
+ ```
298
+
299
+ ##### Layouts
300
+
301
+ Under construction
302
+
303
+ ##### Locals
304
+
305
+ Sometimes, it's desirable to pass additional local variables to partials. It can be done this way:
306
+
307
+ ```erb
308
+ <%= render_notification(@notification, locals: {friends: current_user.friends}) %>
309
+ ```
310
+
311
+ #### Notification views
312
+
313
+ `activity_notification` looks for views in `app/views/activity_notification/notifications/:target`.
314
+
315
+ For example, if you have an notification with `:key` set to `"notification.article.comment.replied"` and rendered it with `:target` set to `:users`, the gem will look for a partial in `app/views/activity_notification/notifications/users/article/comment/_replied.html.(|erb|haml|slim|something_else)`.
316
+
317
+ *Hint*: the `"notification."` prefix in `:key` is completely optional and kept for backwards compatibility, you can skip it in new projects.
318
+
319
+ If you would like to fallback to a partial, you can utilize the `fallback` parameter to specify the path of a partial to use when one is missing:
320
+
321
+ ```erb
322
+ <%= render_notification(@notification, target: :users, fallback: 'default') %>
323
+ ```
324
+
325
+ When used in this manner, if a partial with the specified `:key` cannot be located it will use the partial defined in the `fallback` instead. In the example above this would resolve to `activity_notification/notifications/users/_default.html.(|erb|haml|slim|something_else)`.
326
+
327
+ If you do not specify `:target` option like this,
328
+
329
+ ```erb
330
+ <%= render_notification(@notification, fallback: 'default') %>
331
+ ```
332
+
333
+ the gem will look for a partial in `default` as the target type which means `activity_notification/notifications/default/_default.html.(|erb|haml|slim|something_else)`.
334
+
335
+ If a view file does not exist then ActionView::MisingTemplate will be raised. If you wish to fallback to the old behaviour and use an i18n based translation in this situation you can specify a `:fallback` parameter of `text` to fallback to this mechanism like such:
336
+
337
+ ```erb
338
+ <%= render_notification(@notification, fallback: :text) %>
339
+ ```
340
+
341
+ #### i18n for notifications
342
+
343
+ Translations are used by the `#text` method, to which you can pass additional options in form of a hash. `#render` method uses translations when view templates have not been provided. You can render pure i18n strings by passing `{i18n: true}` to `#render_notification` or `#render`.
344
+
345
+ Translations should be put in your locale `.yml` files. To render pure strings from I18n example structure:
346
+
347
+ ```yaml
348
+ notification:
349
+ user:
350
+ article:
351
+ create: 'Article has been created'
352
+ update: 'Someone has edited the article'
353
+ destroy: 'Some user removed an article!'
354
+ comment:
355
+ replied: "<p>%{notifier_name} posted comment to your article %{article_title}</p>"
356
+ ```
357
+
358
+ This structure is valid for notifications with keys `"notification.article.comment.replied"` or `"article.comment.replied"`. As mentioned before, `"notification."` part of the key is optional. In addition for above example, `%{notifier_name}` and `%{article_title}` are used from parameter field in the notification record.
359
+
360
+ #### Grouping notifications
361
+
362
+ `activity_notification` provides the function for automatically grouping notifications. When you created a notification like this, all *unopened* notifications to the same target will be grouped by `article` set as `:group` options:
363
+
364
+ ```ruby
365
+ @comment.notify User key: 'article.commented_on', group: @comment.article
366
+ ```
367
+
368
+ You can use `group_owners_only` scope to filter owner notifications representing each group:
369
+
370
+ ```ruby
371
+ # custom_notifications_controller.rb
372
+ def index
373
+ @notifications = @target.notifications.group_owners_only
374
+ end
375
+ ```
376
+ `notification_index` and `notification_index_with_attributes` methods also use `group_owners_only` scope internally.
377
+
378
+ And you can render them in a view like this:
379
+ ```erb
380
+ <% if notification.group_member_exists? %>
381
+ <%= "#{notification.notifier.name} and other #{notification.group_member_count} people" %>
382
+ <% else %>
383
+ <%= "#{notification.notifier.name}" %>
384
+ <% end %>
385
+ <%= "posted comments to your article \"#{notification.group.title}\"" %>
386
+ ```
387
+
388
+ This presentation will be shown to target users as `Tom and other 7 people posted comments to your article "Let's use Ruby"`.
389
+
390
+ ### Configuring email notification
391
+
392
+ #### Setup mailer
393
+
394
+ First, you need to set up the default URL options for the `activity_notification` mailer in each environment. Here is a possible configuration for `config/environments/development.rb`:
395
+
396
+ ```ruby
397
+ config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
398
+ ```
399
+
400
+ #### Email templates
401
+
402
+ `activity_notification` will look for email template in the same way as notification views. For example, if you have an notification with `:key` set to `"notification.article.comment.replied"` and target_type `users`, the gem will look for a partial in `app/views/activity_notification/mailer/users/article/comment/_replied.html.(|erb|haml|slim|something_else)`.
403
+
404
+ If this template is missing, the gem will look for a partial in `default` as the target type which means `activity_notification/mailer/default/_default.html.(|erb|haml|slim|something_else)`.
405
+
406
+ #### i18n for email
407
+
408
+ The subject of notification email can be put in your locale `.yml` files as `mail_subject` field:
409
+
410
+ ```yaml
411
+ notification:
412
+ user:
413
+ article:
414
+ comment:
415
+ replied: "<p>%{notifier_name} posted comment to your article %{article_title}</p>"
416
+ mail_subject: 'New comment to your article'
417
+ ```
418
+
419
+ ## Testing
420
+
421
+ Under construction
422
+
423
+ ## Documentation
424
+
425
+ Under construction
426
+
427
+ ## Common examples
428
+
429
+ Under construction
430
+
431
+ ## Help
432
+
433
+ Under construction
434
+
435
+ ## License
436
+
437
+ `activity_notification` project rocks and uses [MIT License](MIT-LICENSE).