Skip to content

Commit

Permalink
Move JsonApi object config to JsonApi adapter
Browse files Browse the repository at this point in the history
Finish #1147
  • Loading branch information
bf4 committed Sep 16, 2015
1 parent 37f286e commit 87d587e
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 54 deletions.
8 changes: 6 additions & 2 deletions docs/general/configuration_options.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,9 @@ The following configuration options can be set on `ActiveModel::Serializer.confi
## JSON API

- `jsonapi_resource_type`: Whether the `type` attributes of resources should be singular or plural. Possible values: `:singular, :plural`. Default: `:plural`.
- `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`.
- `jsonapi_version`: The latest version of the spec the API conforms to. Used when `jsonapi_toplevel_member` is `true`. Default: `'1.0'`.
- `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`.
- `jsonapi_version`: The latest version of the spec the API conforms to.
Used when `jsonapi_toplevel_member` is `true`. Default: `'1.0'`.
- `jsonapi_toplevel_meta`: Optional metadata. Not included if empty.
Used when `jsonapi_toplevel_member` is `true`. Default: `{}`.
3 changes: 1 addition & 2 deletions lib/active_model/serializable_resource.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
require 'set'
module ActiveModel
class SerializableResource
ADAPTER_OPTION_KEYS = Set.new([:include, :fields, :adapter,
:jsonapi_toplevel_meta])
ADAPTER_OPTION_KEYS = Set.new([:include, :fields, :adapter])

# Primary interface to composing a resource with a serializer and adapter.
# @return the serializable_resource, ready for #as_json/#to_json/#serializable_hash.
Expand Down
37 changes: 18 additions & 19 deletions lib/active_model/serializer/adapter/json_api.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
class ActiveModel::Serializer::Adapter::JsonApi < ActiveModel::Serializer::Adapter
# JsonApiObject: namespace for functions that build
# JSON API objects
module JsonApiObject
# Make JSON API top-level jsonapi member opt-in
# ref: http://jsonapi.org/format/#document-top-level
ActiveModel::Serializer.config.jsonapi_toplevel_member = false
ActiveModel::Serializer.config.jsonapi_version = '1.0'
ActiveModel::Serializer.config.jsonapi_toplevel_meta = {}
module JsonApi
VERSION = "1.0"
extend self
def add!(document)
return document unless ActiveModel::Serializer.config.jsonapi_toplevel_member
document.merge!(
jsonapi: { version: VERSION },
)
object = {
jsonapi: {
version: ActiveModel::Serializer.config.jsonapi_version,
meta: ActiveModel::Serializer.config.jsonapi_toplevel_meta
}
}
object[:jsonapi].reject! {|_,v| v.blank? }
document.merge!(object)
end
end
end
Expand All @@ -33,20 +41,11 @@ def initialize(serializer, options = {})

def serializable_hash(options = nil)
options ||= {}
hash =
if serializer.respond_to?(:each)
serializable_hash_for_collection(serializer, options)
else
serializable_hash_for_single_resource(serializer, options)
end

if ActiveModel::Serializer.config.jsonapi_toplevel_member
hash[:jsonapi] = {}
hash[:jsonapi][:version] = ActiveModel::Serializer.config.jsonapi_version
hash[:jsonapi][:meta] = @options[:jsonapi_toplevel_meta] if @options[:jsonapi_toplevel_meta]
if serializer.respond_to?(:each)
serializable_hash_for_collection(serializer, options)
else
serializable_hash_for_single_resource(serializer, options)
end

hash
end

def fragment_cache(cached_hash, non_cached_hash)
Expand Down Expand Up @@ -141,8 +140,8 @@ def relationship_value_for(serializer, options = {})
end

def relationships_for(serializer)
Hash[serializer.associations.map { |association|
[association.key, { data: relationship_value_for(association.serializer, association.options) }]
Hash[serializer.associations.map { |association|
[association.key, { data: relationship_value_for(association.serializer, association.options) }]
}]
end

Expand Down
60 changes: 29 additions & 31 deletions test/adapter/json_api/toplevel_jsonapi_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,58 +27,56 @@ def setup
@author.posts = []
end

def with_config(option, value)
old_value = ActiveModel::Serializer.config[option]
ActiveModel::Serializer.config[option] = value
yield
ensure
ActiveModel::Serializer.config[option] = old_value
def test_toplevel_jsonapi_defaults_to_false
assert_equal config.fetch(:jsonapi_toplevel_member), false
end

def test_disable_toplevel_jsonapi
with_adapter :json_api do
with_config(:jsonapi_toplevel_member, false) do
hash = ActiveModel::SerializableResource.new(@post).serializable_hash
assert_nil(hash[:jsonapi])
end
with_config(jsonapi_toplevel_member: false) do
hash = serialize(@post)
assert_nil(hash[:jsonapi])
end
end

def test_enable_toplevel_jsonapi
with_adapter :json_api do
with_config(:jsonapi_toplevel_member, true) do
hash = ActiveModel::SerializableResource.new(@post).serializable_hash
refute_nil(hash[:jsonapi])
end
with_config(jsonapi_toplevel_member: true) do
hash = serialize(@post)
refute_nil(hash[:jsonapi])
end
end

def test_default_toplevel_jsonapi_version
with_adapter :json_api do
with_config(:jsonapi_toplevel_member, true) do
hash = ActiveModel::SerializableResource.new(@post).serializable_hash
assert_equal('1.0', hash[:jsonapi][:version])
end
with_config(jsonapi_toplevel_member: true) do
hash = serialize(@post)
assert_equal('1.0', hash[:jsonapi][:version])
end
end

def test_toplevel_jsonapi_no_meta
with_adapter :json_api do
with_config(:jsonapi_toplevel_member, true) do
hash = ActiveModel::SerializableResource.new(@post).serializable_hash
assert_nil(hash[:jsonapi][:meta])
end
with_config(jsonapi_toplevel_member: true) do
hash = serialize(@post)
assert_nil(hash[:jsonapi][:meta])
end
end

def test_toplevel_jsonapi_meta
with_adapter :json_api do
with_config(:jsonapi_toplevel_member, true) do
hash = ActiveModel::SerializableResource.new(@post, jsonapi_toplevel_meta: 'custom').serializable_hash
assert_equal('custom', hash[:jsonapi][:meta])
end
new_config = {
jsonapi_toplevel_member: true,
jsonapi_toplevel_meta: {
'copyright': 'Copyright 2015 Example Corp.'
}
}
with_config(new_config) do
hash = serialize(@post)
assert_equal(new_config[:jsonapi_toplevel_meta], hash.fetch(:jsonapi).fetch(:meta))
end
end

private

def serialize(resource, options = {})
serializable(resource, { adapter: :json_api}.merge!(options)).serializable_hash
end
end
end
end
Expand Down
19 changes: 19 additions & 0 deletions test/support/serialization_testing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,30 @@ def before_setup
ActionController::Base.cache_store.clear
end

private

def with_adapter(adapter)
old_adapter = ActiveModel::Serializer.config.adapter
ActiveModel::Serializer.config.adapter = adapter
yield
ensure
ActiveModel::Serializer.config.adapter = old_adapter
end

def config
ActiveModel::Serializer.config
end

def with_config(hash)
old_config = config.dup
ActiveModel::Serializer.config.update(hash)
yield
ensure
ActiveModel::Serializer.config.replace(old_config)
end

def serializable(resource, options = {})
ActiveModel::SerializableResource.new(resource, options)
end

end

0 comments on commit 87d587e

Please sign in to comment.