Skip to content

Commit d1c44c7

Browse files
committed
Update for review per maurogeorge feedback
1 parent b36cc42 commit d1c44c7

File tree

5 files changed

+112
-83
lines changed

5 files changed

+112
-83
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,10 @@ All serializable resources must pass the ActiveModel::Serializer::Lint::Tests.
381381
See the ActiveModelSerializers::Model for a base class that implements the full
382382
API for a plain-old Ruby object (PORO).
383383

384+
## Hooks
385+
386+
To run a hook when ActiveModelSerializers is loaded, use `ActiveSupport.on_load(:active_model_serializers) do end`
387+
384388
## Getting Help
385389

386390
If you find a bug, please report an [Issue](https://github.com/rails-api/active_model_serializers/issues/new).

docs/general/instrumentation.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# Instrumentation
22

3-
ActiveModelSerializers uses the ActiveSupport::Notification API, which
4-
allows for subscribing to events, such as for logging.
3+
ActiveModelSerializers uses the
4+
[ActiveSupport::Notification API](http://guides.rubyonrails.org/active_support_instrumentation.html#subscribing-to-an-event),
5+
which allows for subscribing to events, such as for logging.
56

67
## Events
78

@@ -17,3 +18,20 @@ Payload (example):
1718
adapter: ActiveModel::Serializer::Adapter::Attributes
1819
}
1920
```
21+
22+
Subscribing:
23+
24+
```ruby
25+
ActiveSupport::Notifications.subscribe 'render.active_model_serializers' do |name, started, finished, unique_id, data|
26+
# whatever
27+
end
28+
ActiveSupport::Notifications.subscribe 'render.active_model_serializers' do |*args|
29+
event = ActiveSupport::Notifications::Event.new(*args)
30+
# event.payload
31+
# whatever
32+
end
33+
34+
## [LogSubscriber](http://api.rubyonrails.org/classes/ActiveSupport/LogSubscriber.html)
35+
36+
ActiveModelSerializers includes an `ActiveModelSerializers::LogSubscriber` that attaches to
37+
`render.active_model_serializers`.

lib/action_controller/serialization.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ def get_serializer(resource, options = {})
3131
serializable_resource.serialization_scope ||= serialization_scope
3232
serializable_resource.serialization_scope_name = _serialization_scope
3333
begin
34+
# Necessary to ensure we have an adapter for the serializable resource
35+
# after it has been figured.
36+
# TODO: This logic should be less opaque and probably moved into the SerializableResource.
3437
serializable_resource.tap(&:adapter)
3538
rescue ActiveModel::Serializer::CollectionSerializer::NoSerializerError
3639
resource

lib/active_model_serializers.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
require 'active_model'
22
require 'active_support'
3-
require 'active_support/tagged_logging'
4-
require 'active_support/logger'
53
require 'action_controller'
64
require 'action_controller/railtie'
75
module ActiveModelSerializers

lib/active_model_serializers/logging.rb

Lines changed: 85 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -3,108 +3,114 @@
33
#
44
# https://github.com/rails/rails/blob/280654ef88/activejob/lib/active_job/logging.rb
55
#
6-
module ActiveModelSerializers::Logging
7-
extend ActiveSupport::Concern
6+
module ActiveModelSerializers
7+
module Logging
8+
extend ActiveSupport::Concern
89

9-
included do
10-
include ActiveModelSerializers::Callbacks
11-
extend NotificationMacro
12-
instrument_rendering
13-
end
10+
included do
11+
include ActiveModelSerializers::Callbacks
12+
extend Macros
13+
instrument_rendering
14+
end
1415

15-
module ClassMethods
16-
def instrument_rendering
17-
around_render do |args, block|
18-
tag_logger do
19-
notify_render do
20-
block.call(args)
16+
module ClassMethods
17+
def instrument_rendering
18+
around_render do |args, block|
19+
tag_logger do
20+
notify_render do
21+
block.call(args)
22+
end
2123
end
2224
end
2325
end
2426
end
25-
end
2627

27-
# Adapted from:
28-
# https://github.com/rubygems/rubygems/blob/cb28f5e991/lib/rubygems/deprecate.rb
29-
# Provides a single method +notify+ to be used to declare when
30-
# something a method notifies, with the argument +callback_name+ of the notification callback.
31-
#
32-
# class Adapter
33-
# def self.klass_method
34-
# # ...
35-
# end
36-
#
37-
# def instance_method
38-
# # ...
39-
# end
40-
#
41-
# include ActiveModelSerializers::Logging
42-
# notify :instance_method, :render
43-
#
44-
# class << self
45-
# extend ActiveModelSerializers::Logging::NotificationMacro
46-
# notify :klass_method, :render
47-
# end
48-
# end
49-
module NotificationMacro
50-
##
51-
# Simple notify method that wraps up +name+
52-
# in a dummy method. It notifies on with the +callback_name+ notifier on
53-
# each call to the dummy method, telling what the current serializer and adapter
54-
# are being rendered.
28+
# Macros that can be used to customize the logging of class or instance methods,
29+
# by extending the class or its singleton.
30+
#
5531
# Adapted from:
5632
# https://github.com/rubygems/rubygems/blob/cb28f5e991/lib/rubygems/deprecate.rb
57-
def notify(name, callback_name)
58-
class_eval do
59-
old = "_notifying_#{callback_name}_#{name}"
60-
alias_method old, name
61-
define_method name do |*args, &block|
62-
run_callbacks callback_name do
63-
send old, *args, &block
33+
#
34+
# Provides a single method +notify+ to be used to declare when
35+
# something a method notifies, with the argument +callback_name+ of the notification callback.
36+
#
37+
# class Adapter
38+
# def self.klass_method
39+
# # ...
40+
# end
41+
#
42+
# def instance_method
43+
# # ...
44+
# end
45+
#
46+
# include ActiveModelSerializers::Logging::Macros
47+
# notify :instance_method, :render
48+
#
49+
# class << self
50+
# extend ActiveModelSerializers::Logging::Macros
51+
# notify :klass_method, :render
52+
# end
53+
# end
54+
module Macros
55+
##
56+
# Simple notify method that wraps up +name+
57+
# in a dummy method. It notifies on with the +callback_name+ notifier on
58+
# each call to the dummy method, telling what the current serializer and adapter
59+
# are being rendered.
60+
# Adapted from:
61+
# https://github.com/rubygems/rubygems/blob/cb28f5e991/lib/rubygems/deprecate.rb
62+
def notify(name, callback_name)
63+
class_eval do
64+
old = "_notifying_#{callback_name}_#{name}"
65+
alias_method old, name
66+
define_method name do |*args, &block|
67+
run_callbacks callback_name do
68+
send old, *args, &block
69+
end
6470
end
6571
end
6672
end
6773
end
68-
end
6974

70-
def notify_render(*)
71-
event_name = 'render.active_model_serializers'.freeze
72-
ActiveSupport::Notifications.instrument(event_name, notify_render_payload) do
73-
yield
75+
def notify_render(*)
76+
event_name = 'render.active_model_serializers'.freeze
77+
ActiveSupport::Notifications.instrument(event_name, notify_render_payload) do
78+
yield
79+
end
7480
end
75-
end
7681

77-
def notify_render_payload
78-
{ serializer: serializer, adapter: adapter }
79-
end
82+
def notify_render_payload
83+
{ serializer: serializer, adapter: adapter }
84+
end
8085

81-
private
86+
private
8287

83-
def tag_logger(*tags)
84-
if ActiveModelSerializers.logger.respond_to?(:tagged)
85-
tags.unshift 'AMS'.freeze unless logger_tagged_by_active_model_serializers?
86-
ActiveModelSerializers.logger.tagged(*tags) { yield }
87-
else
88-
yield
88+
def tag_logger(*tags)
89+
if ActiveModelSerializers.logger.respond_to?(:tagged)
90+
tags.unshift 'AMS'.freeze unless logger_tagged_by_active_model_serializers?
91+
ActiveModelSerializers.logger.tagged(*tags) { yield }
92+
else
93+
yield
94+
end
8995
end
90-
end
9196

92-
def logger_tagged_by_active_model_serializers?
93-
ActiveModelSerializers.logger.formatter.current_tags.include?('AMS'.freeze)
94-
end
97+
def logger_tagged_by_active_model_serializers?
98+
ActiveModelSerializers.logger.formatter.current_tags.include?('AMS'.freeze)
99+
end
95100

96-
class LogSubscriber < ActiveSupport::LogSubscriber
97-
def render(event)
98-
info do
99-
serializer = event.payload[:serializer]
100-
adapter = event.payload[:adapter]
101-
duration = event.duration.round(2)
102-
"Rendered #{serializer.name} with #{adapter.class} (#{duration}ms)"
101+
class LogSubscriber < ActiveSupport::LogSubscriber
102+
def render(event)
103+
info do
104+
serializer = event.payload[:serializer]
105+
adapter = event.payload[:adapter]
106+
duration = event.duration.round(2)
107+
"Rendered #{serializer.name} with #{adapter.class} (#{duration}ms)"
108+
end
103109
end
104-
end
105110

106-
def logger
107-
ActiveModelSerializers.logger
111+
def logger
112+
ActiveModelSerializers.logger
113+
end
108114
end
109115
end
110116
end

0 commit comments

Comments
 (0)