Require explicit adapter/serializer to render JSON API errors

- Separate collection errors from resource errors in adapter
- Refactor to ErrorsSerializer; first-class json error methods
- DOCS
- Rails 4.0 requires assert exact exception class, boo
This commit is contained in:
Benjamin Fleischer
2015-12-02 11:56:15 -06:00
parent dfe162638c
commit 96107c56aa
11 changed files with 196 additions and 88 deletions

View File

@@ -18,14 +18,6 @@ module ActiveModel
options.partition { |k, _| ADAPTER_OPTION_KEYS.include? k }.map { |h| Hash[h] }
end
def errors?
if resource.respond_to?(:each)
resource.any? { |elem| elem.respond_to?(:errors) && !elem.errors.empty? }
else
resource.respond_to?(:errors) && !resource.errors.empty?
end
end
def serialization_scope=(scope)
serializer_opts[:scope] = scope
end
@@ -39,11 +31,7 @@ module ActiveModel
end
def adapter
@adapter ||=
begin
adapter_opts[:adapter] = :'json_api/error' if errors?
ActiveModelSerializers::Adapter.create(serializer_instance, adapter_opts)
end
@adapter ||= ActiveModelSerializers::Adapter.create(serializer_instance, adapter_opts)
end
alias_method :adapter_instance, :adapter
@@ -58,7 +46,6 @@ module ActiveModel
@serializer ||=
begin
@serializer = serializer_opts.delete(:serializer)
@serializer = ActiveModel::Serializer::ErrorSerializer if errors?
@serializer ||= ActiveModel::Serializer.serializer_for(resource)
if serializer_opts.key?(:each_serializer)

View File

@@ -2,6 +2,7 @@ require 'thread_safe'
require 'active_model/serializer/collection_serializer'
require 'active_model/serializer/array_serializer'
require 'active_model/serializer/error_serializer'
require 'active_model/serializer/errors_serializer'
require 'active_model/serializer/include_tree'
require 'active_model/serializer/associations'
require 'active_model/serializer/attributes'

View File

@@ -1,2 +1,6 @@
class ActiveModel::Serializer::ErrorSerializer < ActiveModel::Serializer
# @return [Hash<field_name,Array<error_message>>]
def as_json
object.errors.messages
end
end

View File

@@ -0,0 +1,23 @@
require 'active_model/serializer/error_serializer'
class ActiveModel::Serializer::ErrorsSerializer < ActiveModel::Serializer
include Enumerable
delegate :each, to: :@serializers
attr_reader :object, :root
def initialize(resources, options = {})
@root = options[:root]
@object = resources
@serializers = resources.map do |resource|
serializer_class = options.fetch(:serializer) { ActiveModel::Serializer::ErrorSerializer }
serializer_class.new(resource, options.except(:serializer))
end
end
def json_key
nil
end
protected
attr_reader :serializers
end