Skip to content

Commit 61c54bd

Browse files
committed
Merge pull request #1166 from rails-api/clarify_options_variable
Prefer methods over instance variables
2 parents 3f0794b + 9d65f0a commit 61c54bd

File tree

10 files changed

+132
-101
lines changed

10 files changed

+132
-101
lines changed

lib/active_model/serializer.rb

Lines changed: 48 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,16 @@ class << self
4242
end
4343

4444
def self.inherited(base)
45-
base._attributes = self._attributes.try(:dup) || []
46-
base._attributes_keys = self._attributes_keys.try(:dup) || {}
45+
base._attributes = _attributes.try(:dup) || []
46+
base._attributes_keys = _attributes_keys.try(:dup) || {}
4747
base._cache_digest = digest_caller_file(caller.first)
4848
super
4949
end
5050

5151
def self.attributes(*attrs)
5252
attrs = attrs.first if attrs.first.class == Array
53-
@_attributes.concat attrs
54-
@_attributes.uniq!
53+
_attributes.concat(attrs)
54+
_attributes.uniq!
5555

5656
attrs.each do |attr|
5757
define_method attr do
@@ -62,8 +62,8 @@ def self.attributes(*attrs)
6262

6363
def self.attribute(attr, options = {})
6464
key = options.fetch(:key, attr)
65-
@_attributes_keys[attr] = { key: key } if key != attr
66-
@_attributes << key unless @_attributes.include?(key)
65+
self._attributes_keys[attr] = { key: key } if key != attr
66+
self._attributes << key unless _attributes.include?(key)
6767

6868
ActiveModelSerializers.silence_warnings do
6969
define_method key do
@@ -73,16 +73,16 @@ def self.attribute(attr, options = {})
7373
end
7474

7575
def self.fragmented(serializer)
76-
@_fragmented = serializer
76+
self._fragmented = serializer
7777
end
7878

7979
# Enables a serializer to be automatically cached
8080
def self.cache(options = {})
81-
@_cache = ActionController::Base.cache_store if Rails.configuration.action_controller.perform_caching
82-
@_cache_key = options.delete(:key)
83-
@_cache_only = options.delete(:only)
84-
@_cache_except = options.delete(:except)
85-
@_cache_options = (options.empty?) ? nil : options
81+
self._cache = ActionController::Base.cache_store if Rails.configuration.action_controller.perform_caching
82+
self._cache_key = options.delete(:key)
83+
self._cache_only = options.delete(:only)
84+
self._cache_except = options.delete(:except)
85+
self._cache_options = (options.empty?) ? nil : options
8686
end
8787

8888
def self.serializer_for(resource, options = {})
@@ -91,7 +91,7 @@ def self.serializer_for(resource, options = {})
9191
elsif resource.respond_to?(:to_ary)
9292
config.array_serializer
9393
else
94-
options.fetch(:serializer, get_serializer_for(resource.class))
94+
options.fetch(:serializer) { get_serializer_for(resource.class) }
9595
end
9696
end
9797

@@ -104,17 +104,40 @@ def self.root_name
104104
name.demodulize.underscore.sub(/_serializer$/, '') if name
105105
end
106106

107+
def self.serializers_cache
108+
@serializers_cache ||= ThreadSafe::Cache.new
109+
end
110+
111+
def self.digest_caller_file(caller_line)
112+
serializer_file_path = caller_line[CALLER_FILE]
113+
serializer_file_contents = IO.read(serializer_file_path)
114+
Digest::MD5.hexdigest(serializer_file_contents)
115+
end
116+
117+
def self.get_serializer_for(klass)
118+
serializers_cache.fetch_or_store(klass) do
119+
serializer_class_name = "#{klass.name}Serializer"
120+
serializer_class = serializer_class_name.safe_constantize
121+
122+
if serializer_class
123+
serializer_class
124+
elsif klass.superclass
125+
get_serializer_for(klass.superclass)
126+
end
127+
end
128+
end
129+
107130
attr_accessor :object, :root, :meta, :meta_key, :scope
108131

109132
def initialize(object, options = {})
110-
@object = object
111-
@options = options
112-
@root = options[:root]
113-
@meta = options[:meta]
114-
@meta_key = options[:meta_key]
115-
@scope = options[:scope]
116-
117-
scope_name = options[:scope_name]
133+
self.object = object
134+
self.instance_options = options
135+
self.root = instance_options[:root]
136+
self.meta = instance_options[:meta]
137+
self.meta_key = instance_options[:meta_key]
138+
self.scope = instance_options[:scope]
139+
140+
scope_name = instance_options[:scope_name]
118141
if scope_name && !respond_to?(scope_name)
119142
self.class.class_eval do
120143
define_method scope_name, lambda { scope }
@@ -123,7 +146,7 @@ def initialize(object, options = {})
123146
end
124147

125148
def json_key
126-
@root || object.class.model_name.to_s.underscore
149+
root || object.class.model_name.to_s.underscore
127150
end
128151

129152
def attributes(options = {})
@@ -143,29 +166,10 @@ def attributes(options = {})
143166
end
144167
end
145168

146-
def self.serializers_cache
147-
@serializers_cache ||= ThreadSafe::Cache.new
148-
end
149-
150-
def self.digest_caller_file(caller_line)
151-
serializer_file_path = caller_line[CALLER_FILE]
152-
serializer_file_contents = IO.read(serializer_file_path)
153-
Digest::MD5.hexdigest(serializer_file_contents)
154-
end
155-
156-
attr_reader :options
169+
private # rubocop:disable Lint/UselessAccessModifier
157170

158-
def self.get_serializer_for(klass)
159-
serializers_cache.fetch_or_store(klass) do
160-
serializer_class_name = "#{klass.name}Serializer"
161-
serializer_class = serializer_class_name.safe_constantize
162-
163-
if serializer_class
164-
serializer_class
165-
elsif klass.superclass
166-
get_serializer_for(klass.superclass)
167-
end
168-
end
171+
ActiveModelSerializers.silence_warnings do
172+
attr_accessor :instance_options
169173
end
170174
end
171175
end

lib/active_model/serializer/adapter.rb

Lines changed: 4 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class Adapter
1010
autoload :JsonApi
1111
autoload :Null
1212
autoload :FlattenJson
13+
autoload :CachedSerializer
1314

1415
def self.create(resource, options = {})
1516
override = options.delete(:adapter)
@@ -80,11 +81,11 @@ def self.inherited(subclass)
8081
ActiveModel::Serializer::Adapter.register(subclass.to_s.demodulize, subclass)
8182
end
8283

83-
attr_reader :serializer
84+
attr_reader :serializer, :instance_options
8485

8586
def initialize(serializer, options = {})
8687
@serializer = serializer
87-
@options = options
88+
@instance_options = options
8889
end
8990

9091
def serializable_hash(options = nil)
@@ -101,43 +102,12 @@ def fragment_cache(*args)
101102
raise NotImplementedError, 'This is an abstract method. Should be implemented at the concrete adapter.'
102103
end
103104

104-
private
105-
106105
def cache_check(serializer)
107-
@cached_serializer = serializer
108-
@klass = @cached_serializer.class
109-
if is_cached?
110-
@klass._cache.fetch(cache_key, @klass._cache_options) do
111-
yield
112-
end
113-
elsif is_fragment_cached?
114-
FragmentCache.new(self, @cached_serializer, @options).fetch
115-
else
106+
CachedSerializer.new(serializer).cache_check(self) do
116107
yield
117108
end
118109
end
119110

120-
def is_cached?
121-
@klass._cache && !@klass._cache_only && !@klass._cache_except
122-
end
123-
124-
def is_fragment_cached?
125-
@klass._cache_only && !@klass._cache_except || !@klass._cache_only && @klass._cache_except
126-
end
127-
128-
def cache_key
129-
parts = []
130-
parts << object_cache_key
131-
parts << @klass._cache_digest unless @klass._cache_options && @klass._cache_options[:skip_digest]
132-
parts.join('/')
133-
end
134-
135-
def object_cache_key
136-
object_time_safe = @cached_serializer.object.updated_at
137-
object_time_safe = object_time_safe.strftime('%Y%m%d%H%M%S%9N') if object_time_safe.respond_to?(:strftime)
138-
(@klass._cache_key) ? "#{@klass._cache_key}/#{@cached_serializer.object.id}-#{object_time_safe}" : @cached_serializer.object.cache_key
139-
end
140-
141111
def meta
142112
serializer.meta if serializer.respond_to?(:meta)
143113
end
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
module ActiveModel
2+
class Serializer
3+
class Adapter
4+
class CachedSerializer
5+
def initialize(serializer)
6+
@cached_serializer = serializer
7+
@klass = @cached_serializer.class
8+
end
9+
10+
def cache_check(adapter_instance)
11+
if cached?
12+
@klass._cache.fetch(cache_key, @klass._cache_options) do
13+
yield
14+
end
15+
elsif fragment_cached?
16+
FragmentCache.new(adapter_instance, @cached_serializer, adapter_instance.instance_options).fetch
17+
else
18+
yield
19+
end
20+
end
21+
22+
def cached?
23+
@klass._cache && !@klass._cache_only && !@klass._cache_except
24+
end
25+
26+
def fragment_cached?
27+
@klass._cache_only && !@klass._cache_except || !@klass._cache_only && @klass._cache_except
28+
end
29+
30+
def cache_key
31+
parts = []
32+
parts << object_cache_key
33+
parts << @klass._cache_digest unless @klass._cache_options && @klass._cache_options[:skip_digest]
34+
parts.join('/')
35+
end
36+
37+
def object_cache_key
38+
object_time_safe = @cached_serializer.object.updated_at
39+
object_time_safe = object_time_safe.strftime('%Y%m%d%H%M%S%9N') if object_time_safe.respond_to?(:strftime)
40+
(@klass._cache_key) ? "#{@klass._cache_key}/#{@cached_serializer.object.id}-#{object_time_safe}" : @cached_serializer.object.cache_key
41+
end
42+
end
43+
end
44+
end
45+
end

lib/active_model/serializer/adapter/fragment_cache.rb

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ class ActiveModel::Serializer::Adapter::FragmentCache
22
attr_reader :serializer
33

44
def initialize(adapter, serializer, options)
5-
@options = options
5+
@instance_options = options
66
@adapter = adapter
77
@serializer = serializer
88
end
@@ -16,19 +16,23 @@ def fetch
1616
cached_serializer = serializers[:cached].constantize.new(serializer.object)
1717
non_cached_serializer = serializers[:non_cached].constantize.new(serializer.object)
1818

19-
cached_adapter = @adapter.class.new(cached_serializer, @options)
20-
non_cached_adapter = @adapter.class.new(non_cached_serializer, @options)
19+
cached_adapter = adapter.class.new(cached_serializer, instance_options)
20+
non_cached_adapter = adapter.class.new(non_cached_serializer, instance_options)
2121

2222
# Get serializable hash from both
2323
cached_hash = cached_adapter.serializable_hash
2424
non_cached_hash = non_cached_adapter.serializable_hash
2525

2626
# Merge both results
27-
@adapter.fragment_cache(cached_hash, non_cached_hash)
27+
adapter.fragment_cache(cached_hash, non_cached_hash)
2828
end
2929

3030
private
3131

32+
ActiveModelSerializers.silence_warnings do
33+
attr_reader :instance_options, :adapter
34+
end
35+
3236
def cached_attributes(klass, serializers)
3337
attributes = serializer.class._attributes
3438
cached_attributes = (klass._cache_only) ? klass._cache_only : attributes.reject { |attr| klass._cache_except.include?(attr) }

lib/active_model/serializer/adapter/json.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ def serializable_hash(options = nil)
1515

1616
serializer.associations.each do |association|
1717
serializer = association.serializer
18-
opts = association.options
18+
association_options = association.options
1919

2020
if serializer.respond_to?(:each)
2121
array_serializer = serializer
2222
hash[association.key] = array_serializer.map do |item|
2323
cache_check(item) do
24-
item.attributes(opts)
24+
item.attributes(association_options)
2525
end
2626
end
2727
else
@@ -30,8 +30,8 @@ def serializable_hash(options = nil)
3030
cache_check(serializer) do
3131
serializer.attributes(options)
3232
end
33-
elsif opts[:virtual_value]
34-
opts[:virtual_value]
33+
elsif association_options[:virtual_value]
34+
association_options[:virtual_value]
3535
end
3636
end
3737
end

lib/active_model/serializer/adapter/json_api.rb

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ class ActiveModel::Serializer::Adapter::JsonApi < ActiveModel::Serializer::Adapt
55

66
def initialize(serializer, options = {})
77
super
8-
@included = ActiveModel::Serializer::Utils.include_args_to_hash(@options[:include])
8+
@included = ActiveModel::Serializer::Utils.include_args_to_hash(instance_options[:include])
99
fields = options.delete(:fields)
1010
if fields
1111
@fieldset = ActiveModel::Serializer::Fieldset.new(fields, serializer.json_key)
@@ -24,16 +24,20 @@ def serializable_hash(options = nil)
2424
end
2525

2626
def fragment_cache(cached_hash, non_cached_hash)
27-
root = false if @options.include?(:include)
27+
root = false if instance_options.include?(:include)
2828
ActiveModel::Serializer::Adapter::JsonApi::FragmentCache.new.fragment_cache(root, cached_hash, non_cached_hash)
2929
end
3030

3131
private
3232

33+
ActiveModel.silence_warnings do
34+
attr_reader :included, :fieldset
35+
end
36+
3337
def serializable_hash_for_collection(serializer, options)
3438
hash = { data: [] }
3539
serializer.each do |s|
36-
result = self.class.new(s, @options.merge(fieldset: @fieldset)).serializable_hash(options)
40+
result = self.class.new(s, instance_options.merge(fieldset: fieldset)).serializable_hash(options)
3741
hash[:data] << result[:data]
3842

3943
if result[:included]
@@ -85,7 +89,7 @@ def resource_identifier_for(serializer)
8589
end
8690

8791
def resource_object_for(serializer, options = {})
88-
options[:fields] = @fieldset && @fieldset.fields_for(serializer)
92+
options[:fields] = fieldset && fieldset.fields_for(serializer)
8993

9094
cache_check(serializer) do
9195
result = resource_identifier_for(serializer)
@@ -120,12 +124,10 @@ def relationships_for(serializer)
120124
end
121125

122126
def included_for(serializer)
123-
included = @included.flat_map do |inc|
127+
included.flat_map { |inc|
124128
association = serializer.associations.find { |assoc| assoc.key == inc.first }
125129
_included_for(association.serializer, inc.second) if association
126-
end
127-
128-
included.uniq
130+
}.uniq
129131
end
130132

131133
def _included_for(serializer, includes)
@@ -134,7 +136,7 @@ def _included_for(serializer, includes)
134136
else
135137
return [] unless serializer && serializer.object
136138

137-
primary_data = primary_data_for(serializer, @options)
139+
primary_data = primary_data_for(serializer, instance_options)
138140
relationships = relationships_for(serializer)
139141
primary_data[:relationships] = relationships if relationships.any?
140142

0 commit comments

Comments
 (0)