Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FlattenJson adapter no longer inherits Json adapter, renamed to Attributes #1117

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ AllCops:

Style/IndentationConsistency:
Exclude:
- lib/active_model/serializer/adapter/flatten_json.rb
- lib/active_model/serializer/adapter/attributes.rb
- lib/active_model/serializer/adapter/fragment_cache.rb
- lib/active_model/serializer/adapter/json.rb
- lib/active_model/serializer/adapter/json/fragment_cache.rb
Expand All @@ -21,7 +21,7 @@ Style/IndentationConsistency:

Style/IndentationWidth:
Exclude:
- lib/active_model/serializer/adapter/flatten_json.rb
- lib/active_model/serializer/adapter/attributes.rb
- lib/active_model/serializer/adapter/fragment_cache.rb
- lib/active_model/serializer/adapter/json.rb
- lib/active_model/serializer/adapter/json/fragment_cache.rb
Expand All @@ -32,7 +32,7 @@ Style/IndentationWidth:

Style/AccessModifierIndentation:
Exclude:
- lib/active_model/serializer/adapter/flatten_json.rb
- lib/active_model/serializer/adapter/attributes.rb
- lib/active_model/serializer/adapter/fragment_cache.rb
- lib/active_model/serializer/adapter/json.rb
- lib/active_model/serializer/adapter/json/fragment_cache.rb
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ AMS does this through two components: **serializers** and **adapters**.
Serializers describe _which_ attributes and relationships should be serialized.
Adapters describe _how_ attributes and relationships should be serialized.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reminder to my self to note that one literally cannot use a Serializer alone to get a hash or JSON. It is the job of the adapter to compose the attributes-to-be-serialized of each object into the hash or JSON document.


By default AMS will use the **Flatten Json Adapter**. But we strongly advise you to use **JsonApi Adapter** that follows 1.0 of the format specified in [jsonapi.org/format](http://jsonapi.org/format).
By default AMS will use the **Attributes Adapter**. But we strongly advise you to use **JsonApi Adapter** that follows 1.0 of the format specified in [jsonapi.org/format](http://jsonapi.org/format).
Check how to change the adapter in the sections bellow.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing that I don't like about calling the adapter attributes is that it is harder to grep for, esp if we want to rename it again. But, we liked the name in the Slack channel, so until something better..

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup, I'm not sure about the name as well, but have no suggestions so far

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AttributeSerialization?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fields, Properties?? idk. ha


# RELEASE CANDIDATE, PLEASE READ
Expand Down Expand Up @@ -66,7 +66,7 @@ ActiveModel::Serializer.config.adapter = :json_api
You won't need to implement an adapter unless you wish to use a new format or
media type with AMS.

If you want to have a root key on your responses you should use the Json adapter, instead of the default FlattenJson:
If you want to have a root key on your responses you should use the Json adapter, instead of the default Attributes:

```ruby
ActiveModel::Serializer.config.adapter = :json
Expand Down Expand Up @@ -137,7 +137,7 @@ render json: @post, meta: { total: 10 }, meta_key: "custom_meta"
```

`meta` will only be included in your response if you are using an Adapter that supports `root`,
as JsonAPI and Json adapters, the default adapter (FlattenJson) doesn't have `root`.
as JsonAPI and Json adapters, the default adapter (Attributes) doesn't have `root`.

### Using a serializer without `render`

Expand Down Expand Up @@ -190,7 +190,7 @@ end

### Built in Adapters

#### FlattenJSON
#### Attributes

It's the default adapter, it generates a json response without a root key.
Doesn't follow any specifc convention.
Expand Down
6 changes: 3 additions & 3 deletions docs/general/adapters.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
AMS does this through two components: **serializers** and **adapters**.
Serializers describe _which_ attributes and relationships should be serialized.
Adapters describe _how_ attributes and relationships should be serialized.
You can use one of the built-in adapters (```FlattenJSON``` is the default one) or create one by yourself, but you won't need to implement an adapter unless you wish to use a new format or media type with AMS.
You can use one of the built-in adapters (```Attributes``` is the default one) or create one by yourself, but you won't need to implement an adapter unless you wish to use a new format or media type with AMS.

## Built in Adapters

### FlattenJSON - Default
### Attributes - Default

It's the default adapter, it generates a json response without a root key.
Doesn't follow any specifc convention.
Expand Down Expand Up @@ -51,7 +51,7 @@ ActiveModel::Serializer.config.adapter = :json_api
```

If you want to have a root key for each resource in your responses, you should use the Json or
JsonApi adapters instead of the default FlattenJson:
JsonApi adapters instead of the default Attributes:

```ruby
ActiveModel::Serializer.config.adapter = :json
Expand Down
2 changes: 1 addition & 1 deletion docs/general/configuration_options.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ The following configuration options can be set on `ActiveModel::Serializer.confi

## General

- `adapter`: The [adapter](adapters.md) to use. Possible values: `:flatten_json, :json, :json_api`. Default: `:flatten_json`.
- `adapter`: The [adapter](adapters.md) to use. Possible values: `:attributes, :json, :json_api`. Default: `:attributes`.

## JSON API

Expand Down
2 changes: 1 addition & 1 deletion docs/howto/add_pagination_links.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,6 @@ ex.
}
```

### FlattenJSON adapter
### Attributes adapter

This adapter does not allow us to use `meta` key, due to that it is not possible to add pagination links.
2 changes: 1 addition & 1 deletion docs/howto/add_root_key.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# How to add root key

Add the root key to your API is quite simple with AMS. The **Adapter** is what determines the format of your JSON response. The default adapter is the ```FlattenJSON``` which doesn't have the root key, so your response is something similar to:
Add the root key to your API is quite simple with AMS. The **Adapter** is what determines the format of your JSON response. The default adapter is the ```Attributes``` which doesn't have the root key, so your response is something similar to:

```json
{
Expand Down
11 changes: 7 additions & 4 deletions lib/active_model/serializer/adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ class Adapter
ADAPTER_MAP = {}
private_constant :ADAPTER_MAP if defined?(private_constant)
extend ActiveSupport::Autoload
autoload :Attributes
autoload :Null
autoload :FragmentCache
autoload :Json
autoload :JsonApi
autoload :Null
autoload :FlattenJson
autoload :CachedSerializer

def self.create(resource, options = {})
Expand Down Expand Up @@ -74,7 +74,8 @@ def lookup(adapter)
# @api private
def find_by_name(adapter_name)
adapter_name = adapter_name.to_s.classify.tr('API', 'Api')
ActiveModel::Serializer::Adapter.const_get(adapter_name.to_sym) or # rubocop:disable Style/AndOr
"ActiveModel::Serializer::Adapter::#{adapter_name}".safe_constantize ||
"ActiveModel::Serializer::Adapter::#{adapter_name.pluralize}".safe_constantize or # rubocop:disable Style/AndOr
fail UnknownAdapterError
end
private :find_by_name
Expand Down Expand Up @@ -112,12 +113,14 @@ def cache_check(serializer)
end
end

private

def meta
serializer.meta if serializer.respond_to?(:meta)
end

def meta_key
serializer.meta_key || 'meta'
serializer.meta_key || 'meta'.freeze
end

def root
Expand Down
50 changes: 50 additions & 0 deletions lib/active_model/serializer/adapter/attributes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
class ActiveModel::Serializer::Adapter::Attributes < ActiveModel::Serializer::Adapter
def serializable_hash(options = nil)
options ||= {}
if serializer.respond_to?(:each)
result = serializer.map { |s| Attributes.new(s).serializable_hash(options) }
else
hash = {}

core = cache_check(serializer) do
serializer.attributes(options)
end

serializer.associations.each do |association|
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that all this came from the json adapter.
I think I'm getting PRs mixed in my head. bah.

it'll be interesting to see how this plays in to the nested associations stuff.

serializer = association.serializer
association_options = association.options

if serializer.respond_to?(:each)
array_serializer = serializer
hash[association.key] = array_serializer.map do |item|
cache_check(item) do
item.attributes(association_options)
end
end
else
hash[association.key] =
if serializer && serializer.object
cache_check(serializer) do
serializer.attributes(options)
end
elsif association_options[:virtual_value]
association_options[:virtual_value]
end
end
end
result = core.merge hash
end
result
end

def fragment_cache(cached_hash, non_cached_hash)
Json::FragmentCache.new.fragment_cache(cached_hash, non_cached_hash)
end

private

# no-op: Attributes adapter does not include meta data, because it does not support root.
def include_meta(json)
json
end
end
12 changes: 0 additions & 12 deletions lib/active_model/serializer/adapter/flatten_json.rb

This file was deleted.

40 changes: 4 additions & 36 deletions lib/active_model/serializer/adapter/json.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,12 @@ class ActiveModel::Serializer::Adapter::Json < ActiveModel::Serializer::Adapter

def serializable_hash(options = nil)
options ||= {}
if serializer.respond_to?(:each)
result = serializer.map { |s| FlattenJson.new(s).serializable_hash(options) }
else
hash = {}

core = cache_check(serializer) do
serializer.attributes(options)
end

serializer.associations.each do |association|
serializer = association.serializer
association_options = association.options

if serializer.respond_to?(:each)
array_serializer = serializer
hash[association.key] = array_serializer.map do |item|
cache_check(item) do
item.attributes(association_options)
end
end
else
hash[association.key] =
if serializer && serializer.object
cache_check(serializer) do
serializer.attributes(options)
end
elsif association_options[:virtual_value]
association_options[:virtual_value]
end
end
end
result = core.merge hash
end

{ root => result }
{ root => Attributes.new(serializer).serializable_hash(options) }
end

private

def fragment_cache(cached_hash, non_cached_hash)
ActiveModel::Serializer::Adapter::Json::FragmentCache.new().fragment_cache(cached_hash, non_cached_hash)
ActiveModel::Serializer::Adapter::Json::FragmentCache.new.fragment_cache(cached_hash, non_cached_hash)
end
end
2 changes: 1 addition & 1 deletion lib/active_model/serializer/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module Configuration

included do |base|
base.config.array_serializer = ActiveModel::Serializer::ArraySerializer
base.config.adapter = :flatten_json
base.config.adapter = :attributes
base.config.jsonapi_resource_type = :plural
end
end
Expand Down
2 changes: 1 addition & 1 deletion test/adapter_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def test_serializer

def test_create_adapter
adapter = ActiveModel::Serializer::Adapter.create(@serializer)
assert_equal ActiveModel::Serializer::Adapter::FlattenJson, adapter.class
assert_equal ActiveModel::Serializer::Adapter::Attributes, adapter.class
end

def test_create_adapter_with_override
Expand Down
14 changes: 7 additions & 7 deletions test/serializers/adapter_for_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def setup
@previous_adapter = ActiveModel::Serializer.config.adapter
# Eager load adapters
ActiveModel::Serializer::Adapter.eager_load!
[:json_api, :flatten_json, :null, :json].each do |adapter_name|
[:json_api, :attributes, :null, :json].each do |adapter_name|
ActiveModel::Serializer::Adapter.lookup(adapter_name)
end
end
Expand All @@ -18,7 +18,7 @@ def teardown

def test_returns_default_adapter
adapter = ActiveModel::Serializer.adapter
assert_equal ActiveModel::Serializer::Adapter::FlattenJson, adapter
assert_equal ActiveModel::Serializer::Adapter::Attributes, adapter
end

def test_overwrite_adapter_with_symbol
Expand Down Expand Up @@ -68,15 +68,15 @@ def test_adapter_map
expected_adapter_map = {
'json'.freeze => ActiveModel::Serializer::Adapter::Json,
'json_api'.freeze => ActiveModel::Serializer::Adapter::JsonApi,
'flatten_json'.freeze => ActiveModel::Serializer::Adapter::FlattenJson,
'null'.freeze => ActiveModel::Serializer::Adapter::Null
'attributes'.freeze => ActiveModel::Serializer::Adapter::Attributes,
'null'.freeze => ActiveModel::Serializer::Adapter::Null
}
assert_equal ActiveModel::Serializer::Adapter.adapter_map, expected_adapter_map
end

def test_adapters
assert_equal ActiveModel::Serializer::Adapter.adapters.sort, [
'flatten_json'.freeze,
'attributes'.freeze,
'json'.freeze,
'json_api'.freeze,
'null'.freeze
Expand Down Expand Up @@ -114,8 +114,8 @@ def test_lookup_adapter_for_unknown_name
end

def test_adapter
assert_equal ActiveModel::Serializer.config.adapter, :flatten_json
assert_equal ActiveModel::Serializer.adapter, ActiveModel::Serializer::Adapter::FlattenJson
assert_equal ActiveModel::Serializer.config.adapter, :attributes
assert_equal ActiveModel::Serializer.adapter, ActiveModel::Serializer::Adapter::Attributes
end

def test_register_adapter
Expand Down
2 changes: 1 addition & 1 deletion test/serializers/attribute_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def test_json_serializable_hash
def test_attribute_inheritance_with_key
inherited_klass = Class.new(AlternateBlogSerializer)
blog_serializer = inherited_klass.new(@blog)
adapter = ActiveModel::Serializer::Adapter::FlattenJson.new(blog_serializer)
adapter = ActiveModel::Serializer::Adapter::Attributes.new(blog_serializer)
assert_equal({ :id => 1, :title => 'AMS Hints' }, adapter.serializable_hash)
end

Expand Down
2 changes: 1 addition & 1 deletion test/serializers/configuration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def test_array_serializer
end

def test_default_adapter
assert_equal :flatten_json, ActiveModel::Serializer.config.adapter
assert_equal :attributes, ActiveModel::Serializer.config.adapter
end
end
end
Expand Down
8 changes: 4 additions & 4 deletions test/serializers/meta_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def test_meta_is_present_with_root
end

def test_meta_is_not_included_when_root_is_missing
# load_adapter uses FlattenJson Adapter
# load_adapter uses Attributes Adapter
adapter = load_adapter(meta: { total: 10 })
expected = {
id: 1,
Expand Down Expand Up @@ -67,8 +67,8 @@ def test_meta_key_is_used_with_json_api

def test_meta_is_not_present_on_arrays_without_root
serializer = ArraySerializer.new([@blog], meta: { total: 10 })
# FlattenJSON doesn't have support to root
adapter = ActiveModel::Serializer::Adapter::FlattenJson.new(serializer)
# Attributes doesn't have support to root
adapter = ActiveModel::Serializer::Adapter::Attributes.new(serializer)
expected = [{
id: 1,
name: 'AMS Hints',
Expand Down Expand Up @@ -113,7 +113,7 @@ def test_meta_is_present_on_arrays_with_root
private

def load_adapter(options)
options = options.merge(adapter: :flatten_json, serializer: AlternateBlogSerializer)
options = options.merge(adapter: :attributes, serializer: AlternateBlogSerializer)
ActiveModel::SerializableResource.new(@blog, options)
end
end
Expand Down