Merge remote-tracking branch 'upstream/master' into fix-jsonapi-ri

This commit is contained in:
Lucas Hosseini
2015-09-06 17:21:43 +02:00
65 changed files with 1013 additions and 532 deletions

View File

@@ -1,7 +1,6 @@
require 'set'
module ActiveModel
class SerializableResource
ADAPTER_OPTION_KEYS = Set.new([:include, :fields, :adapter])
def initialize(resource, options = {})
@@ -79,6 +78,5 @@ module ActiveModel
ActiveModelSerializers.silence_warnings do
attr_reader :resource, :adapter_opts, :serializer_opts
end
end
end

View File

@@ -13,7 +13,6 @@ module ActiveModel
include Configuration
include Associations
# Matches
# "c:/git/emberjs/ember-crm-backend/app/serializers/lead_serializer.rb:1:in `<top (required)>'"
# AND
@@ -70,7 +69,7 @@ module ActiveModel
ActiveModelSerializers.silence_warnings do
define_method key do
object.read_attribute_for_serialization(attr)
end unless respond_to?(key, false) || _fragmented.respond_to?(attr)
end unless (key != :id && method_defined?(key)) || _fragmented.respond_to?(attr)
end
end

View File

@@ -15,7 +15,7 @@ module ActiveModel
end
def self.adapter_class(adapter)
adapter_name = adapter.to_s.classify.sub("API", "Api")
adapter_name = adapter.to_s.classify.sub('API', 'Api')
"ActiveModel::Serializer::Adapter::#{adapter_name}".safe_constantize
end
@@ -68,12 +68,12 @@ module ActiveModel
parts = []
parts << object_cache_key
parts << @klass._cache_digest unless @klass._cache_options && @klass._cache_options[:skip_digest]
parts.join("/")
parts.join('/')
end
def object_cache_key
object_time_safe = @cached_serializer.object.updated_at
object_time_safe = object_time_safe.strftime("%Y%m%d%H%M%S%9N") if object_time_safe.respond_to?(:strftime)
object_time_safe = object_time_safe.strftime('%Y%m%d%H%M%S%9N') if object_time_safe.respond_to?(:strftime)
(@klass._cache_key) ? "#{@klass._cache_key}/#{@cached_serializer.object.id}-#{object_time_safe}" : @cached_serializer.object.cache_key
end
@@ -82,7 +82,7 @@ module ActiveModel
end
def meta_key
serializer.meta_key || "meta"
serializer.meta_key || 'meta'
end
def root

View File

@@ -2,7 +2,6 @@ module ActiveModel
class Serializer
class Adapter
class FragmentCache
attr_reader :serializer
def initialize(adapter, serializer, options)
@@ -35,7 +34,7 @@ module ActiveModel
def cached_attributes(klass, serializers)
attributes = serializer.class._attributes
cached_attributes = (klass._cache_only) ? klass._cache_only : attributes.reject {|attr| klass._cache_except.include?(attr) }
cached_attributes = (klass._cache_only) ? klass._cache_only : attributes.reject { |attr| klass._cache_except.include?(attr) }
non_cached_attributes = attributes - cached_attributes
cached_attributes.each do |attribute|
@@ -60,7 +59,7 @@ module ActiveModel
Object.const_set cached, Class.new(ActiveModel::Serializer) unless Object.const_defined?(cached)
Object.const_set non_cached, Class.new(ActiveModel::Serializer) unless Object.const_defined?(non_cached)
klass._cache_options ||= {}
klass._cache_options ||= {}
klass._cache_options[:key] = klass._cache_key if klass._cache_key
cached.constantize.cache(klass._cache_options)
@@ -68,7 +67,7 @@ module ActiveModel
cached.constantize.fragmented(serializer)
non_cached.constantize.fragmented(serializer)
serializers = {cached: cached, non_cached: non_cached}
serializers = { cached: cached, non_cached: non_cached }
cached_attributes(klass, serializers)
serializers
end

View File

@@ -46,7 +46,6 @@ module ActiveModel
def fragment_cache(cached_hash, non_cached_hash)
Json::FragmentCache.new().fragment_cache(cached_hash, non_cached_hash)
end
end
end
end

View File

@@ -4,11 +4,9 @@ module ActiveModel
class Adapter
class Json < Adapter
class FragmentCache
def fragment_cache(cached_hash, non_cached_hash)
non_cached_hash.merge cached_hash
end
end
end
end

View File

@@ -159,19 +159,21 @@ module ActiveModel
def add_links(options)
links = @hash.fetch(:links) { {} }
resources = serializer.instance_variable_get(:@resource)
@hash[:links] = add_pagination_links(links, resources, options) if is_paginated?(resources)
collection = serializer.object
if is_paginated?(collection)
@hash[:links] = add_pagination_links(links, collection, options)
end
end
def add_pagination_links(links, resources, options)
pagination_links = JsonApi::PaginationLinks.new(resources, options[:context]).serializable_hash(options)
def add_pagination_links(links, collection, options)
pagination_links = JsonApi::PaginationLinks.new(collection, options[:context]).serializable_hash(options)
links.update(pagination_links)
end
def is_paginated?(resource)
resource.respond_to?(:current_page) &&
resource.respond_to?(:total_pages) &&
resource.respond_to?(:size)
def is_paginated?(collection)
collection.respond_to?(:current_page) &&
collection.respond_to?(:total_pages) &&
collection.respond_to?(:size)
end
end
end

View File

@@ -4,19 +4,17 @@ module ActiveModel
class Adapter
class JsonApi < Adapter
class FragmentCache
def fragment_cache(root, cached_hash, non_cached_hash)
hash = {}
core_cached = cached_hash.first
core_non_cached = non_cached_hash.first
no_root_cache = cached_hash.delete_if {|key, value| key == core_cached[0] }
no_root_non_cache = non_cached_hash.delete_if {|key, value| key == core_non_cached[0] }
no_root_cache = cached_hash.delete_if { |key, value| key == core_cached[0] }
no_root_non_cache = non_cached_hash.delete_if { |key, value| key == core_non_cached[0] }
cached_resource = (core_cached[1]) ? core_cached[1].deep_merge(core_non_cached[1]) : core_non_cached[1]
hash = (root) ? { root => cached_resource } : cached_resource
hash.deep_merge no_root_non_cache.deep_merge no_root_cache
end
end
end
end

View File

@@ -3,23 +3,22 @@ module ActiveModel
class ArraySerializer
NoSerializerError = Class.new(StandardError)
include Enumerable
delegate :each, to: :@objects
delegate :each, to: :@serializers
attr_reader :root, :meta, :meta_key
attr_reader :object, :root, :meta, :meta_key
def initialize(objects, options = {})
def initialize(resources, options = {})
@root = options[:root]
@resource = objects
@objects = objects.map do |object|
serializer_class = options.fetch(
:serializer,
ActiveModel::Serializer.serializer_for(object)
)
@object = resources
@serializers = resources.map do |resource|
serializer_class = options.fetch(:serializer) {
ActiveModel::Serializer.serializer_for(resource)
}
if serializer_class.nil?
fail NoSerializerError, "No serializer found for object: #{object.inspect}"
fail NoSerializerError, "No serializer found for resource: #{resource.inspect}"
else
serializer_class.new(object, options.except(:serializer))
serializer_class.new(resource, options.except(:serializer))
end
end
@meta = options[:meta]
@@ -27,7 +26,7 @@ module ActiveModel
end
def json_key
key = root || @objects.first.try(:json_key) || @resource.try(:name).try(:underscore)
key = root || @serializers.first.try(:json_key) || object.try(:name).try(:underscore)
key.try(:pluralize)
end
end

View File

@@ -7,10 +7,9 @@ module ActiveModel
# @param [Hash{Symbol => Object}] options
#
# @example
# Association.new(:comments, CommentSummarySerializer, embed: :ids)
# Association.new(:comments, CommentSummarySerializer)
#
Association = Struct.new(:name, :serializer, :options) do
# @return [Symbol]
#
def key

View File

@@ -1,7 +1,6 @@
module ActiveModel
class Serializer
class Fieldset
def initialize(fields, root = nil)
@root = root
@raw_fields = fields
@@ -16,7 +15,7 @@ module ActiveModel
fields[key.to_sym] || fields[key.pluralize.to_sym]
end
private
private
ActiveModelSerializers.silence_warnings do
attr_reader :raw_fields, :root
@@ -24,7 +23,7 @@ module ActiveModel
def parsed_fields
if raw_fields.is_a?(Hash)
raw_fields.inject({}) { |h,(k,v)| h[k.to_sym] = v.map(&:to_sym); h}
raw_fields.inject({}) { |h, (k, v)| h[k.to_sym] = v.map(&:to_sym); h }
elsif raw_fields.is_a?(Array)
if root.nil?
raise ArgumentError, 'The root argument must be specified if the fileds argument is an array.'
@@ -36,7 +35,6 @@ module ActiveModel
{}
end
end
end
end
end

View File

@@ -15,7 +15,6 @@ module ActiveModel::Serializer::Lint
# always return +{}+, and the tests would pass. It is up to you to ensure
# that the values are semantically meaningful.
module Tests
# Passes if the object responds to <tt>serializable_hash</tt> and if it takes
# zero or one arguments.
# Fails otherwise.
@@ -23,7 +22,7 @@ module ActiveModel::Serializer::Lint
# <tt>serializable_hash</tt> returns a hash representation of a object's attributes.
# Typically, it is implemented by including ActiveModel::Serialization.
def test_serializable_hash
assert_respond_to resource, :serializable_hash, "The resource should respond to serializable_hash"
assert_respond_to resource, :serializable_hash, 'The resource should respond to serializable_hash'
resource.serializable_hash
resource.serializable_hash(nil)
end
@@ -35,8 +34,18 @@ module ActiveModel::Serializer::Lint
# <tt>read_attribute_for_serialization</tt> gets the attribute value for serialization
# Typically, it is implemented by including ActiveModel::Serialization.
def test_read_attribute_for_serialization
assert_respond_to resource, :read_attribute_for_serialization, "The resource should respond to read_attribute_for_serialization"
assert_equal resource.method(:read_attribute_for_serialization).arity, 1
assert_respond_to resource, :read_attribute_for_serialization, 'The resource should respond to read_attribute_for_serialization'
actual_arity = resource.method(:read_attribute_for_serialization).arity
if defined?(::Rubinius)
# 1 for def read_attribute_for_serialization(name); end
# -2 for alias :read_attribute_for_serialization :send for rbx because :shrug:
assert_includes [1, -2], actual_arity, "expected #{actual_arity.inspect} to be 1 or -2"
else
# using absolute value since arity is:
# 1 for def read_attribute_for_serialization(name); end
# -1 for alias :read_attribute_for_serialization :send
assert_includes [1, -1], actual_arity, "expected #{actual_arity.inspect} to be 1 or -1"
end
end
# Passes if the object responds to <tt>as_json</tt> and if it takes
@@ -68,7 +77,7 @@ module ActiveModel::Serializer::Lint
end
# Passes if the object responds to <tt>cache_key</tt> and if it takes no
# arguments.
# arguments (Rails 4.0) or a splat (Rails 4.1+).
# Fails otherwise.
#
# <tt>cache_key</tt> returns a (self-expiring) unique key for the object,
@@ -76,7 +85,11 @@ module ActiveModel::Serializer::Lint
# It is not required unless caching is enabled.
def test_cache_key
assert_respond_to resource, :cache_key
assert_equal resource.method(:cache_key).arity, 0
actual_arity = resource.method(:cache_key).arity
# using absolute value since arity is:
# 0 for Rails 4.1+, *timestamp_names
# -1 for Rails 4.0, no arguments
assert_includes [-1, 0], actual_arity, "expected #{actual_arity.inspect} to be 0 or -1"
end
# Passes if the object responds to <tt>id</tt> and if it takes no
@@ -112,6 +125,5 @@ module ActiveModel::Serializer::Lint
def assert_instance_of(result, name)
assert result.instance_of?(name), "#{result} should be an instance of #{name}"
end
end
end

View File

@@ -1,5 +1,5 @@
module ActiveModel
class Serializer
VERSION = "0.10.0.rc2"
VERSION = '0.10.0.rc2'
end
end