Skip to content

Commit 87d587e

Browse files
committed
Move JsonApi object config to JsonApi adapter
Finish rails-api#1147
1 parent 37f286e commit 87d587e

File tree

5 files changed

+73
-54
lines changed

5 files changed

+73
-54
lines changed

docs/general/configuration_options.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,9 @@ The following configuration options can be set on `ActiveModel::Serializer.confi
99
## JSON API
1010

1111
- `jsonapi_resource_type`: Whether the `type` attributes of resources should be singular or plural. Possible values: `:singular, :plural`. Default: `:plural`.
12-
- `jsonapi_toplevel_member`: Whether to include a [top level JSON API member](http://jsonapi.org/format/#document-jsonapi-object) in the response document. Default: `false`.
13-
- `jsonapi_version`: The latest version of the spec the API conforms to. Used when `jsonapi_toplevel_member` is `true`. Default: `'1.0'`.
12+
- `jsonapi_toplevel_member`: Whether to include a [top level JSON API member](http://jsonapi.org/format/#document-jsonapi-object)
13+
in the response document. Default: `false`.
14+
- `jsonapi_version`: The latest version of the spec the API conforms to.
15+
Used when `jsonapi_toplevel_member` is `true`. Default: `'1.0'`.
16+
- `jsonapi_toplevel_meta`: Optional metadata. Not included if empty.
17+
Used when `jsonapi_toplevel_member` is `true`. Default: `{}`.

lib/active_model/serializable_resource.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
require 'set'
22
module ActiveModel
33
class SerializableResource
4-
ADAPTER_OPTION_KEYS = Set.new([:include, :fields, :adapter,
5-
:jsonapi_toplevel_meta])
4+
ADAPTER_OPTION_KEYS = Set.new([:include, :fields, :adapter])
65

76
# Primary interface to composing a resource with a serializer and adapter.
87
# @return the serializable_resource, ready for #as_json/#to_json/#serializable_hash.

lib/active_model/serializer/adapter/json_api.rb

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
class ActiveModel::Serializer::Adapter::JsonApi < ActiveModel::Serializer::Adapter
2+
# JsonApiObject: namespace for functions that build
3+
# JSON API objects
24
module JsonApiObject
35
# Make JSON API top-level jsonapi member opt-in
46
# ref: http://jsonapi.org/format/#document-top-level
57
ActiveModel::Serializer.config.jsonapi_toplevel_member = false
8+
ActiveModel::Serializer.config.jsonapi_version = '1.0'
9+
ActiveModel::Serializer.config.jsonapi_toplevel_meta = {}
610
module JsonApi
7-
VERSION = "1.0"
811
extend self
912
def add!(document)
1013
return document unless ActiveModel::Serializer.config.jsonapi_toplevel_member
11-
document.merge!(
12-
jsonapi: { version: VERSION },
13-
)
14+
object = {
15+
jsonapi: {
16+
version: ActiveModel::Serializer.config.jsonapi_version,
17+
meta: ActiveModel::Serializer.config.jsonapi_toplevel_meta
18+
}
19+
}
20+
object[:jsonapi].reject! {|_,v| v.blank? }
21+
document.merge!(object)
1422
end
1523
end
1624
end
@@ -33,20 +41,11 @@ def initialize(serializer, options = {})
3341

3442
def serializable_hash(options = nil)
3543
options ||= {}
36-
hash =
37-
if serializer.respond_to?(:each)
38-
serializable_hash_for_collection(serializer, options)
39-
else
40-
serializable_hash_for_single_resource(serializer, options)
41-
end
42-
43-
if ActiveModel::Serializer.config.jsonapi_toplevel_member
44-
hash[:jsonapi] = {}
45-
hash[:jsonapi][:version] = ActiveModel::Serializer.config.jsonapi_version
46-
hash[:jsonapi][:meta] = @options[:jsonapi_toplevel_meta] if @options[:jsonapi_toplevel_meta]
44+
if serializer.respond_to?(:each)
45+
serializable_hash_for_collection(serializer, options)
46+
else
47+
serializable_hash_for_single_resource(serializer, options)
4748
end
48-
49-
hash
5049
end
5150

5251
def fragment_cache(cached_hash, non_cached_hash)
@@ -141,8 +140,8 @@ def relationship_value_for(serializer, options = {})
141140
end
142141

143142
def relationships_for(serializer)
144-
Hash[serializer.associations.map { |association|
145-
[association.key, { data: relationship_value_for(association.serializer, association.options) }]
143+
Hash[serializer.associations.map { |association|
144+
[association.key, { data: relationship_value_for(association.serializer, association.options) }]
146145
}]
147146
end
148147

test/adapter/json_api/toplevel_jsonapi_test.rb

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -27,58 +27,56 @@ def setup
2727
@author.posts = []
2828
end
2929

30-
def with_config(option, value)
31-
old_value = ActiveModel::Serializer.config[option]
32-
ActiveModel::Serializer.config[option] = value
33-
yield
34-
ensure
35-
ActiveModel::Serializer.config[option] = old_value
30+
def test_toplevel_jsonapi_defaults_to_false
31+
assert_equal config.fetch(:jsonapi_toplevel_member), false
3632
end
3733

3834
def test_disable_toplevel_jsonapi
39-
with_adapter :json_api do
40-
with_config(:jsonapi_toplevel_member, false) do
41-
hash = ActiveModel::SerializableResource.new(@post).serializable_hash
42-
assert_nil(hash[:jsonapi])
43-
end
35+
with_config(jsonapi_toplevel_member: false) do
36+
hash = serialize(@post)
37+
assert_nil(hash[:jsonapi])
4438
end
4539
end
4640

4741
def test_enable_toplevel_jsonapi
48-
with_adapter :json_api do
49-
with_config(:jsonapi_toplevel_member, true) do
50-
hash = ActiveModel::SerializableResource.new(@post).serializable_hash
51-
refute_nil(hash[:jsonapi])
52-
end
42+
with_config(jsonapi_toplevel_member: true) do
43+
hash = serialize(@post)
44+
refute_nil(hash[:jsonapi])
5345
end
5446
end
5547

5648
def test_default_toplevel_jsonapi_version
57-
with_adapter :json_api do
58-
with_config(:jsonapi_toplevel_member, true) do
59-
hash = ActiveModel::SerializableResource.new(@post).serializable_hash
60-
assert_equal('1.0', hash[:jsonapi][:version])
61-
end
49+
with_config(jsonapi_toplevel_member: true) do
50+
hash = serialize(@post)
51+
assert_equal('1.0', hash[:jsonapi][:version])
6252
end
6353
end
6454

6555
def test_toplevel_jsonapi_no_meta
66-
with_adapter :json_api do
67-
with_config(:jsonapi_toplevel_member, true) do
68-
hash = ActiveModel::SerializableResource.new(@post).serializable_hash
69-
assert_nil(hash[:jsonapi][:meta])
70-
end
56+
with_config(jsonapi_toplevel_member: true) do
57+
hash = serialize(@post)
58+
assert_nil(hash[:jsonapi][:meta])
7159
end
7260
end
7361

7462
def test_toplevel_jsonapi_meta
75-
with_adapter :json_api do
76-
with_config(:jsonapi_toplevel_member, true) do
77-
hash = ActiveModel::SerializableResource.new(@post, jsonapi_toplevel_meta: 'custom').serializable_hash
78-
assert_equal('custom', hash[:jsonapi][:meta])
79-
end
63+
new_config = {
64+
jsonapi_toplevel_member: true,
65+
jsonapi_toplevel_meta: {
66+
'copyright': 'Copyright 2015 Example Corp.'
67+
}
68+
}
69+
with_config(new_config) do
70+
hash = serialize(@post)
71+
assert_equal(new_config[:jsonapi_toplevel_meta], hash.fetch(:jsonapi).fetch(:meta))
8072
end
8173
end
74+
75+
private
76+
77+
def serialize(resource, options = {})
78+
serializable(resource, { adapter: :json_api}.merge!(options)).serializable_hash
79+
end
8280
end
8381
end
8482
end

test/support/serialization_testing.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,30 @@ def before_setup
33
ActionController::Base.cache_store.clear
44
end
55

6+
private
7+
68
def with_adapter(adapter)
79
old_adapter = ActiveModel::Serializer.config.adapter
810
ActiveModel::Serializer.config.adapter = adapter
911
yield
1012
ensure
1113
ActiveModel::Serializer.config.adapter = old_adapter
1214
end
15+
16+
def config
17+
ActiveModel::Serializer.config
18+
end
19+
20+
def with_config(hash)
21+
old_config = config.dup
22+
ActiveModel::Serializer.config.update(hash)
23+
yield
24+
ensure
25+
ActiveModel::Serializer.config.replace(old_config)
26+
end
27+
28+
def serializable(resource, options = {})
29+
ActiveModel::SerializableResource.new(resource, options)
30+
end
31+
1332
end

0 commit comments

Comments
 (0)