listenable 0.1.0 → 0.1.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 +4 -4
- data/README.md +51 -0
- data/lib/listenable/railtie.rb +20 -13
- data/lib/listenable/version.rb +1 -1
- data/lib/listenable.rb +2 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ebe46a89c412b54c70f0af2f7851f46176dfd08c3dc5a611ef61c35d0bea1717
|
|
4
|
+
data.tar.gz: c19ed7b192adc50833b432058cfcdf652add0401bbbca28e869c282186ef7e88
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6083b9a19eb74cceaec96942846f3a7b7754bf0ed27f42686f67351e8b6bd7246392c485a7b0ad4e35d909d85eb2b0f4f2cf33ebf0529ff475c9ed11b9857e68
|
|
7
|
+
data.tar.gz: 2b4c5d0b93694b35f3431f9cef48794182a621e8f937fc01bb745b895d3edbff5b38ce27c42a78c69622fecd2d2e5e1d35d5b2e171f5080dd2fd4344619c6ebd
|
data/README.md
CHANGED
|
@@ -72,6 +72,57 @@ Under the hood:
|
|
|
72
72
|
| `on_updated` | `after_update` |
|
|
73
73
|
| `on_deleted` | `after_destroy` |
|
|
74
74
|
|
|
75
|
+
## Runtime Toggle
|
|
76
|
+
By default, listeners are always active in development and production.
|
|
77
|
+
|
|
78
|
+
You can enable/disable them dynamically at runtime using:
|
|
79
|
+
|
|
80
|
+
```ruby
|
|
81
|
+
Listenable.enabled = false # disable all listeners
|
|
82
|
+
Listenable.enabled = true # re-enable listeners
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
This does not require restarting your Rails server or test suite.
|
|
86
|
+
|
|
87
|
+
## RSpec/Test Integration
|
|
88
|
+
You usually don’t want listeners firing in tests (e.g. sending jobs or emails).
|
|
89
|
+
|
|
90
|
+
Disable them globally in your test suite:
|
|
91
|
+
|
|
92
|
+
```ruby
|
|
93
|
+
# spec/rails_helper.rb
|
|
94
|
+
RSpec.configure do |config|
|
|
95
|
+
config.before(:suite) do
|
|
96
|
+
Listenable.enabled = false
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Enable listeners selectively
|
|
100
|
+
config.around(:each, listenable: true) do |example|
|
|
101
|
+
prev = Listenable.enabled
|
|
102
|
+
Listenable.enabled = true
|
|
103
|
+
example.run
|
|
104
|
+
Listenable.enabled = prev
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Now:
|
|
110
|
+
|
|
111
|
+
```ruby
|
|
112
|
+
RSpec.describe User do
|
|
113
|
+
it 'does not fire listeners by default' do
|
|
114
|
+
expect(UserListener).not_to receive(:on_created)
|
|
115
|
+
User.create!(name: 'Pedro')
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it 'fires listeners when enabled', listenable: true do
|
|
119
|
+
expect(UserListener).to receive(:on_created)
|
|
120
|
+
User.create!(name: 'Pedro')
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
|
|
75
126
|
## Development
|
|
76
127
|
|
|
77
128
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/lib/listenable/railtie.rb
CHANGED
|
@@ -4,13 +4,13 @@ module Listenable
|
|
|
4
4
|
class Railtie < Rails::Railtie
|
|
5
5
|
initializer "listenable.load" do
|
|
6
6
|
Rails.application.config.to_prepare do
|
|
7
|
-
# Load all listeners (supports
|
|
7
|
+
# Load all listeners (recursive, supports namespaced)
|
|
8
8
|
Dir[Rails.root.join("app/listeners/**/*.rb")].each { |f| require_dependency f }
|
|
9
9
|
|
|
10
|
-
#
|
|
10
|
+
# Find all listener classes
|
|
11
11
|
ObjectSpace.each_object(Class).select { |klass| klass < Listenable }.each do |listener_class|
|
|
12
12
|
model_class_name = listener_class.name.sub("Listener", "")
|
|
13
|
-
model_class
|
|
13
|
+
model_class = model_class_name.safe_constantize
|
|
14
14
|
next unless model_class
|
|
15
15
|
|
|
16
16
|
listener_class.pending_hooks.each do |hook|
|
|
@@ -19,22 +19,29 @@ module Listenable
|
|
|
19
19
|
method = "on_#{action}"
|
|
20
20
|
event = "#{model_class_name.underscore}.#{action}"
|
|
21
21
|
|
|
22
|
-
#
|
|
22
|
+
# Unsubscribe duplicates
|
|
23
23
|
ActiveSupport::Notifications.notifier.listeners_for(event).each do |subscriber|
|
|
24
24
|
ActiveSupport::Notifications.unsubscribe(subscriber)
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
# Inject
|
|
28
|
-
model_class.
|
|
29
|
-
|
|
27
|
+
# Inject AR callback once per model/event
|
|
28
|
+
injected_events = model_class.instance_variable_get(:@_listenable_injected_events) || []
|
|
29
|
+
unless injected_events.include?(event)
|
|
30
|
+
model_class.send(callback) do
|
|
31
|
+
next unless Listenable.enabled
|
|
32
|
+
ActiveSupport::Notifications.instrument(event, record: self)
|
|
33
|
+
end
|
|
34
|
+
injected_events << event
|
|
35
|
+
model_class.instance_variable_set(:@_listenable_injected_events, injected_events)
|
|
30
36
|
end
|
|
31
37
|
|
|
32
|
-
# Subscribe listener
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
# Subscribe listener (runtime-guarded)
|
|
39
|
+
if listener_class.respond_to?(method)
|
|
40
|
+
ActiveSupport::Notifications.subscribe(event) do |*args|
|
|
41
|
+
next unless Listenable.enabled
|
|
42
|
+
_name, _start, _finish, _id, payload = args
|
|
43
|
+
listener_class.public_send(method, payload[:record])
|
|
44
|
+
end
|
|
38
45
|
end
|
|
39
46
|
end
|
|
40
47
|
end
|
data/lib/listenable/version.rb
CHANGED
data/lib/listenable.rb
CHANGED