acts_as_notifier 0.0.1
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 +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +186 -0
- data/Rakefile +36 -0
- data/lib/acts_as_notifier.rb +185 -0
- data/lib/acts_as_notifier/config.rb +5 -0
- data/lib/acts_as_notifier/version.rb +3 -0
- data/test/acts_as_notifier/acts_as_notifier_test.rb +44 -0
- data/test/acts_as_notifier/conditions_test.rb +42 -0
- data/test/acts_as_notifier/config_test.rb +37 -0
- data/test/acts_as_notifier/mailer_test.rb +46 -0
- data/test/acts_as_notifier/recipients_test.rb +51 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/mailers/my_mailer.rb +27 -0
- data/test/dummy/app/models/widget.rb +65 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +59 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +58 -0
- data/test/dummy/db/migrate/20131229201627_create_widgets.rb +9 -0
- data/test/dummy/db/schema.rb +22 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +21 -0
- data/test/dummy/log/test.log +41137 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/test_helper.rb +17 -0
- metadata +232 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b54dedfd2daec809d63e1158f2f8a6c0f7a3e1d1
|
4
|
+
data.tar.gz: 008889b4a39b1d0ce4db7bfe072c4d35f22f1031
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 59b79b96dd4b6656d0efcec8bc4d5ceb165fd863b5eb45bcfc2d3e81c7245b00ab9f5e446db2ceff712c282682063720ede9f10e8061dcff797baab6d427e756
|
7
|
+
data.tar.gz: a482837b9a95c9778193e998dde01e867608529269e21844bbdb406c1fcfeaf046759ba29222d5d7a9000925b7c7742c2f8874e00871c0b2cd79e2132bfe7997
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Michael Johnson
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
# acts_as_notifier
|
2
|
+
|
3
|
+
Easily define ActiveRecord callbacks that notify users of changes via email. Acts_as_notifier dries up your code with
|
4
|
+
a simple, readable DSL, the ability to configure defaults, and by using delayed_job automatically if enabled. The DSL
|
5
|
+
looks especially good when you have multiple notifications defined in a model.
|
6
|
+
|
7
|
+
Instead of this:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
class MyModel < ActiveRecord::Base
|
11
|
+
def after_create
|
12
|
+
if alerts_enabled?
|
13
|
+
if MyMailer.respond_to?(:delay)
|
14
|
+
MyMailer.delay.new_widget_alert(get_recipients, self)
|
15
|
+
else
|
16
|
+
MyMailer.new_widget_alert(get_recipients, self).deliver
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
```
|
22
|
+
|
23
|
+
With acts_as_notifier you write this:
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
# in config/initializers/acts_as_notifier.rb
|
27
|
+
ActsAsNotifier::Config.default_mailer = :MyMailer
|
28
|
+
ActsAsNotifier::Config.default_mailer = :new_widget_alert
|
29
|
+
|
30
|
+
class MyModel < ActiveRecord::Base
|
31
|
+
acts_as_notifier do
|
32
|
+
after_create do
|
33
|
+
notify :get_recipients, :if => :alerts_enabled?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
```
|
38
|
+
|
39
|
+
## When Should I Use This?
|
40
|
+
|
41
|
+
Honestly, using an ActiveRecord callback to trigger email notifications is an [anti-pattern](#soapbox).
|
42
|
+
Acts_as_notifier is a good solution when you have an existing Rails app, possibly with overly-complicated controllers,
|
43
|
+
and refactoring is not feasible. In that case, acts_as_notifier gets you up and running quickly and hides some of the
|
44
|
+
added complexity.
|
45
|
+
|
46
|
+
## Installation
|
47
|
+
|
48
|
+
Add this line to your application's Gemfile:
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
gem 'acts_as_notifier'
|
52
|
+
```
|
53
|
+
|
54
|
+
And then execute:
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
$ bundle
|
58
|
+
```
|
59
|
+
|
60
|
+
Or install it yourself as:
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
$ gem install acts_as_notifier
|
64
|
+
```
|
65
|
+
|
66
|
+
## Usage
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
# in config/initializers/acts_as_notifier.rb
|
70
|
+
ActsAsNotifier::Config.default_mailer = :MyMailer
|
71
|
+
ActsAsNotifier::Config.default_mailer = :change_notification
|
72
|
+
|
73
|
+
# in app/models/my_model.rb
|
74
|
+
class MyModel < ActiveRecord::Base
|
75
|
+
acts_as_notifier do
|
76
|
+
after_create do
|
77
|
+
notify recipients, options
|
78
|
+
end
|
79
|
+
after_update do
|
80
|
+
notify recipients, options
|
81
|
+
end
|
82
|
+
after_save do
|
83
|
+
notify recipients, options
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# in app/mailers/my_mailer.rb
|
89
|
+
class MyMailer < ActionMailer::Base
|
90
|
+
default from: 'test@example.com'
|
91
|
+
|
92
|
+
def change_notification(recipients, model)
|
93
|
+
mail(to: recipients, subject: "A #{model.class} with ID #{model.id} was changed")
|
94
|
+
end
|
95
|
+
end
|
96
|
+
```
|
97
|
+
|
98
|
+
### recipients
|
99
|
+
|
100
|
+
Can be a string containing email addresses, any object with an 'email' method, an array of strings/objects,
|
101
|
+
or a proc or symbolic method name returning any of the above. Procs will be passed the options hash as a parameter.
|
102
|
+
Note that to make sure you get the up-to-date recipients at runtime, you will normally use a proc.
|
103
|
+
|
104
|
+
Examples:
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
notify 'bob@somewhere.com', options
|
108
|
+
notify :find_admin_users, options
|
109
|
+
|
110
|
+
# note use of a proc to lazy-evaluate the ActiveRecord query
|
111
|
+
notify Proc.new { User.where(:should_notify, true) }, options
|
112
|
+
|
113
|
+
# pass yourself custom options in addition to the acts_as_notifiers options
|
114
|
+
notify :get_recipients, :role => :admins
|
115
|
+
def self.get_recipients(options)
|
116
|
+
User.find_all_by_role(options[:role])
|
117
|
+
end
|
118
|
+
```
|
119
|
+
|
120
|
+
### options
|
121
|
+
|
122
|
+
<table>
|
123
|
+
<tr><td>:if</td><td>A string, proc, or name of a method that must evaluate to a truthy value in order for the notification to be sent. Procs and strings are evaluated in the context of the model instance. Procs are be passed the options hash as a parameter.</td></tr>
|
124
|
+
<tr><td>:mailer</td><td>A class inheriting from ActionMailer::Base, may be a string or symbol or actual class.</td></tr>
|
125
|
+
<tr><td>:method</td><td>Mailer method to invoke. Should accept recipients string and the ActiveRecord model as params.</td></tr>
|
126
|
+
<tr><td>custom</td><td>Any additional options will be saved and passed to :if and recipients procs.</td></tr>
|
127
|
+
</table>
|
128
|
+
|
129
|
+
Examples:
|
130
|
+
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
acts_as_notifier do
|
134
|
+
after_create do
|
135
|
+
# different ways of specifying :if condition
|
136
|
+
notify :recipients, :if => 'alerts_enabled?'
|
137
|
+
notify :recipients, :if => :alerts_enabled?
|
138
|
+
notify :recipients, :if => proc { alerts_enabled? }
|
139
|
+
|
140
|
+
# passing your own custom option to an if condition proc
|
141
|
+
notify :recipients, :if => proc {|opts| alerts_enabled_for_role?(opts[:role]) }, :role => :admin
|
142
|
+
|
143
|
+
# specifying a mailer
|
144
|
+
notify :recipients, :mailer => 'MyMailer'
|
145
|
+
notify :recipients, :mailer => :MyMailer
|
146
|
+
notify :recipients, :mailer => MyMailer
|
147
|
+
|
148
|
+
# specifying mailer method (in MyMailer class, def new_record_notification(recipients, model))
|
149
|
+
notify :recipients, :mailer => MyMailer, :method => :new_record_notification
|
150
|
+
|
151
|
+
# complete example
|
152
|
+
notify proc { User.where(wants_alerts: true) }, :if => :alerts_enabled?, :mailer => MyMailer, :method => :new_widget_alert
|
153
|
+
end
|
154
|
+
x
|
155
|
+
# another complete example
|
156
|
+
after_save do
|
157
|
+
notify :owner, :if => ->(widget){ widget.broken? }, :mailer => MyMailer, :method => :broken_widget_alert
|
158
|
+
end
|
159
|
+
end
|
160
|
+
```
|
161
|
+
|
162
|
+
## Configuration
|
163
|
+
|
164
|
+
<table>
|
165
|
+
<tr><td>ActsAsNotifier::Config.use_delayed_job=</td><td>true/false</td></tr>
|
166
|
+
<tr><td>ActsAsNotifier::Config.default_mailer=</td><td>class inheriting from ActionMailer::Base</td></tr>
|
167
|
+
<tr><td>ActsAsNotifier::Config.default_method=</td><td>mailer method to invoke, takes recipient string and ActiveRecord model as params</td></tr>
|
168
|
+
<tr><td>ActsAsNotifier::Config.disabled=</td><td>true/false, can be globally enabled or disabled at any time</td></tr>
|
169
|
+
</table>
|
170
|
+
|
171
|
+
## Contributing
|
172
|
+
|
173
|
+
1. Fork it
|
174
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
175
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
176
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
177
|
+
5. Create new Pull Request
|
178
|
+
|
179
|
+
## <a name="soapbox"></a>Soapbox
|
180
|
+
|
181
|
+
Why do I consider using ActiveRecord callbacks to trigger email notifications an anti-pattern? Callback-based behaviors
|
182
|
+
are difficult to disable or isolate in testing and can result in mysterious, difficult-to-find bugs. In this particular
|
183
|
+
case, using them violates the single responsibility principle in that a model should only be concerned with persisting
|
184
|
+
your data. It also creates undesirable connections between your model, other models, and mailer classes. A better
|
185
|
+
solution is to build business logic classes that handle creating and updating models, sending notifications, and are
|
186
|
+
easier to isolate for testing.
|
data/Rakefile
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'ActsAsNotifier'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
Bundler::GemHelper.install_tasks
|
24
|
+
|
25
|
+
require 'rake/testtask'
|
26
|
+
|
27
|
+
Rake::TestTask.new(:test) do |t|
|
28
|
+
t.libs << 'lib'
|
29
|
+
t.libs << 'test'
|
30
|
+
t.pattern = 'test/**/*_test.rb'
|
31
|
+
t.verbose = false
|
32
|
+
end
|
33
|
+
|
34
|
+
task :default => :test
|
35
|
+
|
36
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,185 @@
|
|
1
|
+
require "acts_as_notifier/version"
|
2
|
+
require "acts_as_notifier/config"
|
3
|
+
|
4
|
+
# Allows an ActiveRecord model to tie notification emails to create and save callbacks with conditions
|
5
|
+
#
|
6
|
+
# Usage:
|
7
|
+
# acts_as_notifier do
|
8
|
+
# after_create/save/update do
|
9
|
+
# notify recipients, options
|
10
|
+
# end
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# Params:
|
14
|
+
# recipients - can be a string containing email addresses, any object with an 'email' method, an array of
|
15
|
+
# strings/objects, or a proc or symbolic method name returning any of the above. procs will be
|
16
|
+
# passed the options hash as a parameter.
|
17
|
+
#
|
18
|
+
# options
|
19
|
+
# :if - string to eval, proc, or method name, !!result must equal true for notification to be sent. procs will
|
20
|
+
# be passed the options hash as a parameter.
|
21
|
+
# :mailer - Typically a class inheriting from ActionMailer::Base.
|
22
|
+
# May be any class or object with a method accepting a recipients string and instance of model that triggered the notification.
|
23
|
+
# May also be a string or symbol that evals to a class or object.
|
24
|
+
# :method - mailer class method to invoke, should accept recipient list and sending ActiveRecord model as params
|
25
|
+
# custom - any additional options can be saved in the action and will be available to procs
|
26
|
+
#
|
27
|
+
# Examples:
|
28
|
+
# acts_as_notifier do
|
29
|
+
# after_create do
|
30
|
+
# notify proc { User.where(wants_alerts: true) }, :if => proc { send_alert? }, :mailer => MyMailer, :method => :new_widget_alert
|
31
|
+
# end
|
32
|
+
# after_save do
|
33
|
+
# notify :owner, :if => ->widget{ widget.broken? }, :mailer => MyMailer, :method => :broken_widget_alert
|
34
|
+
# end
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# Configuration:
|
38
|
+
# ActsAsNotifier::Config.use_delayed_job = true/false
|
39
|
+
# ActsAsNotifier::Config.default_mailer = a class inheriting from ActionMailer::Base
|
40
|
+
# ActsAsNotifier::Config.default_method = mailer class method to invoke, should accept recipient list and sending
|
41
|
+
# ActiveRecord model as params
|
42
|
+
# ActsAsNotifier::Config.disabled = true/false, can be globally enabled or disabled at any time
|
43
|
+
|
44
|
+
module ActsAsNotifier
|
45
|
+
extend ActiveSupport::Concern
|
46
|
+
|
47
|
+
module ClassMethods
|
48
|
+
def acts_as_notifier(&block)
|
49
|
+
cattr_accessor :notifier_actions
|
50
|
+
self.notifier_actions = NotificationDsl.evaluate(&block).presence || []
|
51
|
+
include LocalInstanceMethods
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
module LocalInstanceMethods
|
56
|
+
extend ActiveSupport::Concern
|
57
|
+
|
58
|
+
included do
|
59
|
+
after_create :notifier_create_handler
|
60
|
+
after_save :notifier_save_handler
|
61
|
+
after_update :notifier_update_handler
|
62
|
+
end
|
63
|
+
|
64
|
+
# find a notification action matching options and trigger it, ignoring conditions
|
65
|
+
def force_notification(options = {})
|
66
|
+
opts = options.to_a
|
67
|
+
action = self.class.notifier_actions.find { |action| action.to_a & opts == opts }
|
68
|
+
notifier_send(action)
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def notifier_create_handler
|
74
|
+
notifier_handler(:after_create) unless ActsAsNotifier::Config.disabled
|
75
|
+
end
|
76
|
+
|
77
|
+
def notifier_save_handler
|
78
|
+
notifier_handler(:after_save) unless ActsAsNotifier::Config.disabled
|
79
|
+
end
|
80
|
+
|
81
|
+
def notifier_update_handler
|
82
|
+
notifier_handler(:after_update) unless ActsAsNotifier::Config.disabled
|
83
|
+
end
|
84
|
+
|
85
|
+
def notifier_handler(callback_type)
|
86
|
+
self.class.notifier_actions.each do |action|
|
87
|
+
notifier_send(action) if action[:callback_type].to_sym == callback_type && notifier_conditions_satisfied?(action)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def notifier_conditions_satisfied?(action)
|
92
|
+
condition = action[:if]
|
93
|
+
condition = case condition
|
94
|
+
when String
|
95
|
+
instance_eval(condition)
|
96
|
+
when Proc
|
97
|
+
instance_exec(action, &condition)
|
98
|
+
when Symbol
|
99
|
+
self.send(condition)
|
100
|
+
when nil
|
101
|
+
true
|
102
|
+
else
|
103
|
+
condition
|
104
|
+
end
|
105
|
+
!!condition
|
106
|
+
end
|
107
|
+
|
108
|
+
def notifier_recipients(action)
|
109
|
+
recipients = action[:recipients]
|
110
|
+
recipients = case recipients
|
111
|
+
when Proc
|
112
|
+
instance_exec(action, &recipients)
|
113
|
+
when Symbol
|
114
|
+
self.send(recipients)
|
115
|
+
else
|
116
|
+
recipients
|
117
|
+
end
|
118
|
+
recipients = [ recipients ] unless recipients.is_a?(Array)
|
119
|
+
recipient_list = recipients.map {|r| r.respond_to?(:email) ? r.email : r }.join(', ')
|
120
|
+
recipient_list
|
121
|
+
end
|
122
|
+
|
123
|
+
def notifier_send(action)
|
124
|
+
if (recipients = notifier_recipients(action)).present?
|
125
|
+
mailer, method = notifier_get_mailer(action)
|
126
|
+
if ActsAsNotifier::Config.use_delayed_job && mailer.respond_to?(:delay)
|
127
|
+
mailer.delay.send(method, recipients, self)
|
128
|
+
else
|
129
|
+
message = mailer.send(method, recipients, self)
|
130
|
+
message.deliver if message.respond_to?(:deliver)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def notifier_get_mailer(action)
|
136
|
+
mailer = action[:mailer] || ActsAsNotifier::Config.default_mailer
|
137
|
+
mailer = eval(mailer.to_s) if mailer.is_a?(String) || mailer.is_a?(Symbol)
|
138
|
+
raise "ActsAsNotifier invalid mailer configuration, mailer not specified" unless mailer.present?
|
139
|
+
|
140
|
+
method = action[:method] || ActsAsNotifier::Config.default_method
|
141
|
+
raise "ActsAsNotifier invalid mailer method configuration, method not specified" unless method.present?
|
142
|
+
raise "ActsAsNotifier invalid mailer method configuration, method must be a string or symbol" unless method.is_a?(String) || method.is_a?(Symbol)
|
143
|
+
raise "ActsAsNotifier invalid mailer method configuration, #{method} is not a valid method of #{mailer.to_s}" unless mailer.respond_to?(method)
|
144
|
+
return mailer, method
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
class NotificationDsl
|
149
|
+
attr_accessor :notification_actions
|
150
|
+
|
151
|
+
class << self
|
152
|
+
def evaluate(&script)
|
153
|
+
self.new.tap {|inst| inst.instance_eval(&script)}.notification_actions
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def initialize
|
158
|
+
@current_callback_type = nil
|
159
|
+
@notification_actions = []
|
160
|
+
end
|
161
|
+
|
162
|
+
def after_create(&block)
|
163
|
+
@current_callback_type = :after_create
|
164
|
+
instance_eval(&block)
|
165
|
+
end
|
166
|
+
|
167
|
+
def after_save(&block)
|
168
|
+
@current_callback_type = :after_save
|
169
|
+
instance_eval(&block)
|
170
|
+
end
|
171
|
+
|
172
|
+
def after_update(&block)
|
173
|
+
@current_callback_type = :after_update
|
174
|
+
instance_eval(&block)
|
175
|
+
end
|
176
|
+
|
177
|
+
def notify(recipients, options = {})
|
178
|
+
action = { recipients: recipients, callback_type: @current_callback_type }.merge(options || {})
|
179
|
+
@notification_actions << action
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
end
|
184
|
+
|
185
|
+
ActiveRecord::Base.send(:include, ActsAsNotifier)
|