Skip to content

Commit ab1e2af

Browse files
committed
Merge pull request #1138 from bf4/introduce_adapter_base
Introduce Adapter::Base
2 parents 7cf0e93 + 19de5f7 commit ab1e2af

30 files changed

+125
-99
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
### 0.10.0
22

3+
Breaking changes:
4+
* Adapters now inherit Adapter::Base. 'Adapter' is now a module, no longer a class. [@bf4], #1138
5+
* using a class as a namespace that you also inherit from is complicated and circular at time i.e.
6+
buggy (see https://github.com/rails-api/active_model_serializers/pull/1177)
7+
* The class methods on Adapter aren't necessarily related to the instance methods, they're more
8+
Adapter functions
9+
* named `Base` because it's a Rails-ism
10+
* It helps to isolate and highlight what the Adapter interface actually is
11+
12+
Features:
313
* adds adapters pattern
414
* adds support for `meta` and `meta_key` [@kurko]
515
* adds method to override association [@kurko]
@@ -12,3 +22,7 @@
1222
* adds FlattenJSON as default adapter [@joaomdmoura]
1323
* adds support for `pagination links` at top level of JsonApi adapter [@bacarini]
1424
* adds extended format for `include` option to JsonApi adapter [@beauby]
25+
26+
Fixes:
27+
28+
Misc:

lib/active_model/serializer/adapter.rb

Lines changed: 18 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,30 @@
11
module ActiveModel
22
class Serializer
3-
class Adapter
3+
module Adapter
44
UnknownAdapterError = Class.new(ArgumentError)
55
ADAPTER_MAP = {}
66
private_constant :ADAPTER_MAP if defined?(private_constant)
77
require 'active_model/serializer/adapter/fragment_cache'
88
require 'active_model/serializer/adapter/cached_serializer'
99

10-
def self.create(resource, options = {})
11-
override = options.delete(:adapter)
12-
klass = override ? adapter_class(override) : ActiveModel::Serializer.adapter
13-
klass.new(resource, options)
14-
end
10+
class << self # All methods are class functions
11+
def new(*args)
12+
fail ArgumentError, 'Adapters inherit from Adapter::Base.' \
13+
"Adapter.new called with args: '#{args.inspect}', from" \
14+
"'caller[0]'."
15+
end
1516

16-
# @see ActiveModel::Serializer::Adapter.lookup
17-
def self.adapter_class(adapter)
18-
ActiveModel::Serializer::Adapter.lookup(adapter)
19-
end
17+
def create(resource, options = {})
18+
override = options.delete(:adapter)
19+
klass = override ? adapter_class(override) : ActiveModel::Serializer.adapter
20+
klass.new(resource, options)
21+
end
22+
23+
# @see ActiveModel::Serializer::Adapter.lookup
24+
def adapter_class(adapter)
25+
ActiveModel::Serializer::Adapter.lookup(adapter)
26+
end
2027

21-
# Only the Adapter class has these methods.
22-
# None of the sublasses have them.
23-
class << ActiveModel::Serializer::Adapter
2428
# @return Hash<adapter_name, adapter_class>
2529
def adapter_map
2630
ADAPTER_MAP
@@ -76,58 +80,8 @@ def find_by_name(adapter_name)
7680
private :find_by_name
7781
end
7882

79-
# Automatically register adapters when subclassing
80-
def self.inherited(subclass)
81-
ActiveModel::Serializer::Adapter.register(subclass)
82-
end
83-
84-
attr_reader :serializer, :instance_options
85-
86-
def initialize(serializer, options = {})
87-
@serializer = serializer
88-
@instance_options = options
89-
end
90-
91-
def serializable_hash(options = nil)
92-
raise NotImplementedError, 'This is an abstract method. Should be implemented at the concrete adapter.'
93-
end
94-
95-
def as_json(options = nil)
96-
hash = serializable_hash(options)
97-
include_meta(hash)
98-
hash
99-
end
100-
101-
def fragment_cache(*args)
102-
raise NotImplementedError, 'This is an abstract method. Should be implemented at the concrete adapter.'
103-
end
104-
105-
def cache_check(serializer)
106-
CachedSerializer.new(serializer).cache_check(self) do
107-
yield
108-
end
109-
end
110-
111-
private
112-
113-
def meta
114-
serializer.meta if serializer.respond_to?(:meta)
115-
end
116-
117-
def meta_key
118-
serializer.meta_key || 'meta'.freeze
119-
end
120-
121-
def root
122-
serializer.json_key.to_sym if serializer.json_key
123-
end
124-
125-
def include_meta(json)
126-
json[meta_key] = meta if meta
127-
json
128-
end
129-
13083
# Gotta be at the bottom to use the code above it :(
84+
require 'active_model/serializer/adapter/base'
13185
require 'active_model/serializer/adapter/null'
13286
require 'active_model/serializer/adapter/attributes'
13387
require 'active_model/serializer/adapter/json'

lib/active_model/serializer/adapter/attributes.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module ActiveModel
22
class Serializer
3-
class Adapter
4-
class Attributes < Adapter
3+
module Adapter
4+
class Attributes < Base
55
def serializable_hash(options = nil)
66
options ||= {}
77
if serializer.respond_to?(:each)
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
module ActiveModel
2+
class Serializer
3+
module Adapter
4+
class Base
5+
# Automatically register adapters when subclassing
6+
def self.inherited(subclass)
7+
ActiveModel::Serializer::Adapter.register(subclass)
8+
end
9+
10+
attr_reader :serializer, :instance_options
11+
12+
def initialize(serializer, options = {})
13+
@serializer = serializer
14+
@instance_options = options
15+
end
16+
17+
def serializable_hash(_options = nil)
18+
fail NotImplementedError, 'This is an abstract method. Should be implemented at the concrete adapter.'
19+
end
20+
21+
def as_json(options = nil)
22+
hash = serializable_hash(options)
23+
include_meta(hash)
24+
hash
25+
end
26+
27+
def fragment_cache(*_args)
28+
fail NotImplementedError, 'This is an abstract method. Should be implemented at the concrete adapter.'
29+
end
30+
31+
def cache_check(serializer)
32+
CachedSerializer.new(serializer).cache_check(self) do
33+
yield
34+
end
35+
end
36+
37+
private
38+
39+
def meta
40+
serializer.meta if serializer.respond_to?(:meta)
41+
end
42+
43+
def meta_key
44+
serializer.meta_key || 'meta'.freeze
45+
end
46+
47+
def root
48+
serializer.json_key.to_sym if serializer.json_key
49+
end
50+
51+
def include_meta(json)
52+
json[meta_key] = meta if meta
53+
json
54+
end
55+
end
56+
end
57+
end
58+
end

lib/active_model/serializer/adapter/cached_serializer.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module ActiveModel
22
class Serializer
3-
class Adapter
3+
module Adapter
44
class CachedSerializer
55
def initialize(serializer)
66
@cached_serializer = serializer

lib/active_model/serializer/adapter/fragment_cache.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module ActiveModel
22
class Serializer
3-
class Adapter
3+
module Adapter
44
class FragmentCache
55
attr_reader :serializer
66

lib/active_model/serializer/adapter/json.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module ActiveModel
22
class Serializer
3-
class Adapter
4-
class Json < Adapter
3+
module Adapter
4+
class Json < Base
55
extend ActiveSupport::Autoload
66
autoload :FragmentCache
77

lib/active_model/serializer/adapter/json/fragment_cache.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module ActiveModel
22
class Serializer
3-
class Adapter
3+
module Adapter
44
class Json
55
class FragmentCache
66
def fragment_cache(cached_hash, non_cached_hash)

lib/active_model/serializer/adapter/json_api.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module ActiveModel
22
class Serializer
3-
class Adapter
4-
class JsonApi < Adapter
3+
module Adapter
4+
class JsonApi < Base
55
extend ActiveSupport::Autoload
66
autoload :PaginationLinks
77
autoload :FragmentCache

lib/active_model/serializer/adapter/json_api/fragment_cache.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module ActiveModel
22
class Serializer
3-
class Adapter
3+
module Adapter
44
class JsonApi
55
class FragmentCache
66
def fragment_cache(root, cached_hash, non_cached_hash)

0 commit comments

Comments
 (0)