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

Introduce Adapter::Base #1138

Merged
merged 1 commit into from
Sep 20, 2015
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
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
### 0.10.0

Breaking changes:
* Adapters now inherit Adapter::Base. 'Adapter' is now a module, no longer a class. [@bf4], #1138
* using a class as a namespace that you also inherit from is complicated and circular at time i.e.
buggy (see https://github.com/rails-api/active_model_serializers/pull/1177)
* The class methods on Adapter aren't necessarily related to the instance methods, they're more
Adapter functions
* named `Base` because it's a Rails-ism
* It helps to isolate and highlight what the Adapter interface actually is

Features:
* adds adapters pattern
* adds support for `meta` and `meta_key` [@kurko]
* adds method to override association [@kurko]
Expand All @@ -12,3 +22,7 @@
* adds FlattenJSON as default adapter [@joaomdmoura]
Copy link
Contributor

Choose a reason for hiding this comment

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

There should be a note somewhere stating that the FlattenJSON adapter changed name.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, that's why I wanted a label for 'add to changelog' for all the times we haven't done it

* adds support for `pagination links` at top level of JsonApi adapter [@bacarini]
* adds extended format for `include` option to JsonApi adapter [@beauby]

Fixes:

Misc:
82 changes: 18 additions & 64 deletions lib/active_model/serializer/adapter.rb
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
module ActiveModel
class Serializer
class Adapter
module Adapter
Copy link
Member Author

Choose a reason for hiding this comment

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

possible source of error

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed

UnknownAdapterError = Class.new(ArgumentError)
ADAPTER_MAP = {}
private_constant :ADAPTER_MAP if defined?(private_constant)
require 'active_model/serializer/adapter/fragment_cache'
require 'active_model/serializer/adapter/cached_serializer'

def self.create(resource, options = {})
override = options.delete(:adapter)
klass = override ? adapter_class(override) : ActiveModel::Serializer.adapter
klass.new(resource, options)
end
class << self # All methods are class functions
def new(*args)
fail ArgumentError, 'Adapters inherit from Adapter::Base.' \
"Adapter.new called with args: '#{args.inspect}', from" \
"'caller[0]'."
end
Copy link
Member Author

Choose a reason for hiding this comment

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

Just in case.. but perhaps I could write a better message.. is really meant to be a helpful deprecation fast failure


# @see ActiveModel::Serializer::Adapter.lookup
def self.adapter_class(adapter)
ActiveModel::Serializer::Adapter.lookup(adapter)
end
def create(resource, options = {})
override = options.delete(:adapter)
klass = override ? adapter_class(override) : ActiveModel::Serializer.adapter
klass.new(resource, options)
end

# @see ActiveModel::Serializer::Adapter.lookup
def adapter_class(adapter)
ActiveModel::Serializer::Adapter.lookup(adapter)
end

# Only the Adapter class has these methods.
# None of the sublasses have them.
class << ActiveModel::Serializer::Adapter
# @return Hash<adapter_name, adapter_class>
def adapter_map
ADAPTER_MAP
Expand Down Expand Up @@ -76,58 +80,8 @@ def find_by_name(adapter_name)
private :find_by_name
end

# Automatically register adapters when subclassing
def self.inherited(subclass)
ActiveModel::Serializer::Adapter.register(subclass)
end

attr_reader :serializer, :instance_options

def initialize(serializer, options = {})
@serializer = serializer
@instance_options = options
end

def serializable_hash(options = nil)
raise NotImplementedError, 'This is an abstract method. Should be implemented at the concrete adapter.'
end

def as_json(options = nil)
hash = serializable_hash(options)
include_meta(hash)
hash
end

def fragment_cache(*args)
raise NotImplementedError, 'This is an abstract method. Should be implemented at the concrete adapter.'
end

def cache_check(serializer)
CachedSerializer.new(serializer).cache_check(self) do
yield
end
end

private

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

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

def root
serializer.json_key.to_sym if serializer.json_key
end

def include_meta(json)
json[meta_key] = meta if meta
json
end

# Gotta be at the bottom to use the code above it :(
require 'active_model/serializer/adapter/base'
require 'active_model/serializer/adapter/null'
require 'active_model/serializer/adapter/attributes'
require 'active_model/serializer/adapter/json'
Expand Down
4 changes: 2 additions & 2 deletions lib/active_model/serializer/adapter/attributes.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module ActiveModel
class Serializer
class Adapter
class Attributes < Adapter
module Adapter
class Attributes < Base
def serializable_hash(options = nil)
options ||= {}
if serializer.respond_to?(:each)
Expand Down
58 changes: 58 additions & 0 deletions lib/active_model/serializer/adapter/base.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
module ActiveModel
class Serializer
module Adapter
class Base
# Automatically register adapters when subclassing
def self.inherited(subclass)
ActiveModel::Serializer::Adapter.register(subclass)
end

attr_reader :serializer, :instance_options

def initialize(serializer, options = {})
@serializer = serializer
@instance_options = options
end

def serializable_hash(_options = nil)
fail NotImplementedError, 'This is an abstract method. Should be implemented at the concrete adapter.'
end

def as_json(options = nil)
hash = serializable_hash(options)
include_meta(hash)
hash
end

def fragment_cache(*_args)
fail NotImplementedError, 'This is an abstract method. Should be implemented at the concrete adapter.'
end

def cache_check(serializer)
CachedSerializer.new(serializer).cache_check(self) do
yield
end
end

private

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

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

def root
serializer.json_key.to_sym if serializer.json_key
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the rationale behind calling it root in the adapter and json_key in the serializer?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think just evolution...

end

def include_meta(json)
Copy link
Contributor

Choose a reason for hiding this comment

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

It's probably not within the realm of this PR, but I think we should stay away from side effects as much as possible when unnecessary.

Copy link
Member Author

Choose a reason for hiding this comment

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

yup

json[meta_key] = meta if meta
json
end
end
end
end
end
2 changes: 1 addition & 1 deletion lib/active_model/serializer/adapter/cached_serializer.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module ActiveModel
class Serializer
class Adapter
module Adapter
class CachedSerializer
def initialize(serializer)
@cached_serializer = serializer
Expand Down
2 changes: 1 addition & 1 deletion lib/active_model/serializer/adapter/fragment_cache.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module ActiveModel
class Serializer
class Adapter
module Adapter
class FragmentCache
attr_reader :serializer

Expand Down
4 changes: 2 additions & 2 deletions lib/active_model/serializer/adapter/json.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module ActiveModel
class Serializer
class Adapter
class Json < Adapter
module Adapter
class Json < Base
extend ActiveSupport::Autoload
autoload :FragmentCache

Expand Down
2 changes: 1 addition & 1 deletion lib/active_model/serializer/adapter/json/fragment_cache.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module ActiveModel
class Serializer
class Adapter
module Adapter
class Json
class FragmentCache
def fragment_cache(cached_hash, non_cached_hash)
Expand Down
4 changes: 2 additions & 2 deletions lib/active_model/serializer/adapter/json_api.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module ActiveModel
class Serializer
class Adapter
class JsonApi < Adapter
module Adapter
class JsonApi < Base
extend ActiveSupport::Autoload
autoload :PaginationLinks
autoload :FragmentCache
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module ActiveModel
class Serializer
class Adapter
module Adapter
class JsonApi
class FragmentCache
def fragment_cache(root, cached_hash, non_cached_hash)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module ActiveModel
class Serializer
class Adapter
class JsonApi < Adapter
module Adapter
class JsonApi < Base
class PaginationLinks
FIRST_PAGE = 1

Expand Down
4 changes: 2 additions & 2 deletions lib/active_model/serializer/adapter/null.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module ActiveModel
class Serializer
class Adapter
class Null < Adapter
module Adapter
class Null < Base
def serializable_hash(options = nil)
{}
end
Expand Down
2 changes: 1 addition & 1 deletion test/adapter/fragment_cache_test.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require 'test_helper'
module ActiveModel
class Serializer
class Adapter
module Adapter
class FragmentCacheTest < Minitest::Test
def setup
@spam = Spam::UnrelatedLink.new(id: 'spam-id-1')
Expand Down
2 changes: 1 addition & 1 deletion test/adapter/json/belongs_to_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module ActiveModel
class Serializer
class Adapter
module Adapter
class Json
class BelongsToTest < Minitest::Test
def setup
Expand Down
2 changes: 1 addition & 1 deletion test/adapter/json/collection_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module ActiveModel
class Serializer
class Adapter
module Adapter
class Json
class Collection < Minitest::Test
def setup
Expand Down
2 changes: 1 addition & 1 deletion test/adapter/json/has_many_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module ActiveModel
class Serializer
class Adapter
module Adapter
class Json
class HasManyTestTest < Minitest::Test
def setup
Expand Down
2 changes: 1 addition & 1 deletion test/adapter/json_api/belongs_to_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module ActiveModel
class Serializer
class Adapter
module Adapter
class JsonApi
class BelongsToTest < Minitest::Test
def setup
Expand Down
2 changes: 1 addition & 1 deletion test/adapter/json_api/collection_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module ActiveModel
class Serializer
class Adapter
module Adapter
class JsonApi
class CollectionTest < Minitest::Test
def setup
Expand Down
2 changes: 1 addition & 1 deletion test/adapter/json_api/has_many_embed_ids_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module ActiveModel
class Serializer
class Adapter
module Adapter
class JsonApi
class HasManyEmbedIdsTest < Minitest::Test
def setup
Expand Down
2 changes: 1 addition & 1 deletion test/adapter/json_api/has_many_explicit_serializer_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module ActiveModel
class Serializer
class Adapter
module Adapter
class JsonApi
# Test 'has_many :assocs, serializer: AssocXSerializer'
class HasManyExplicitSerializerTest < Minitest::Test
Expand Down
2 changes: 1 addition & 1 deletion test/adapter/json_api/has_many_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module ActiveModel
class Serializer
class Adapter
module Adapter
class JsonApi
class HasManyTest < Minitest::Test
def setup
Expand Down
2 changes: 1 addition & 1 deletion test/adapter/json_api/has_one_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module ActiveModel
class Serializer
class Adapter
module Adapter
class JsonApi
class HasOneTest < Minitest::Test
def setup
Expand Down
2 changes: 1 addition & 1 deletion test/adapter/json_api/json_api_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module ActiveModel
class Serializer
class Adapter
module Adapter
class JsonApiTest < Minitest::Test
def setup
ActionController::Base.cache_store.clear
Expand Down
2 changes: 1 addition & 1 deletion test/adapter/json_api/linked_test.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require 'test_helper'
module ActiveModel
class Serializer
class Adapter
module Adapter
class JsonApi
class LinkedTest < Minitest::Test
def setup
Expand Down
2 changes: 1 addition & 1 deletion test/adapter/json_api/pagination_links_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

module ActiveModel
class Serializer
class Adapter
module Adapter
class JsonApi
class PaginationLinksTest < Minitest::Test
URI = 'http://example.com'
Expand Down
2 changes: 1 addition & 1 deletion test/adapter/json_api/resource_type_config_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module ActiveModel
class Serializer
class Adapter
module Adapter
class JsonApi
class ResourceTypeConfigTest < Minitest::Test
def setup
Expand Down
Loading