From 8fe1aee255e3ba5803c8d3bcb0195bf8a4a4f9c8 Mon Sep 17 00:00:00 2001 From: Tashiro Date: Thu, 11 Feb 2021 20:14:14 +0900 Subject: [PATCH] add raise_cannot_infer_root_key_error to config --- lib/active_model/serializer.rb | 2 ++ .../serializer/collection_serializer.rb | 13 ++++++++-- test/collection_serializer_test.rb | 24 +++++++++++++++++-- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index 0533fdac..5e347790 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -146,6 +146,8 @@ module ActiveModel config.jsonapi_include_toplevel_object = false config.jsonapi_use_foreign_key_on_belongs_to_relationship = false config.include_data_default = true + # Raise ActiveModel::Serializer::CollectionSerializer::CannotInferRootKeyError when cannot infer root key from collection type + config.raise_cannot_infer_root_key_error = true # For configuring how serializers are found. # This should be an array of procs. diff --git a/lib/active_model/serializer/collection_serializer.rb b/lib/active_model/serializer/collection_serializer.rb index 7aae7769..d60d331a 100644 --- a/lib/active_model/serializer/collection_serializer.rb +++ b/lib/active_model/serializer/collection_serializer.rb @@ -48,8 +48,11 @@ module ActiveModel key ||= object.respond_to?(:name) ? object.name && object.name.underscore : nil # 4. key may be nil for empty collection and no serializer option key &&= key.pluralize - # 5. fail if the key cannot be determined - key || fail(ArgumentError, 'Cannot infer root key from collection type. Please specify the root or each_serializer option, or render a JSON String') + if raise_cannot_infer_root_key_error? + # 5. fail if the key cannot be determined + key || fail(CannotInferRootKeyError, 'Cannot infer root key from collection type. Please specify the root or each_serializer option, or render a JSON String') + end + key end # rubocop:enable Metrics/CyclomaticComplexity @@ -60,12 +63,18 @@ module ActiveModel object.respond_to?(:size) end + class CannotInferRootKeyError < StandardError; end + protected attr_reader :serializers, :options private + def raise_cannot_infer_root_key_error? + ActiveModelSerializers.config.raise_cannot_infer_root_key_error + end + def serializers_from_resources serializer_context_class = options.fetch(:serializer_context_class, ActiveModel::Serializer) object.map do |resource| diff --git a/test/collection_serializer_test.rb b/test/collection_serializer_test.rb index be649151..856cbed7 100644 --- a/test/collection_serializer_test.rb +++ b/test/collection_serializer_test.rb @@ -22,6 +22,8 @@ module ActiveModel type 'messages' end + class NonTypeSerializer < ActiveModel::Serializer; end + def setup @singular_model = SingularModel.new @has_many_model = HasManyModel.new @@ -95,18 +97,36 @@ module ActiveModel resource = [] resource.define_singleton_method(:name) { nil } serializer = collection_serializer.new(resource) - assert_raise ArgumentError do + assert_raise ActiveModel::Serializer::CollectionSerializer::CannotInferRootKeyError do serializer.json_key end end def test_json_key_with_resource_without_name_and_no_serializers serializer = collection_serializer.new([]) - assert_raise ArgumentError do + assert_raise ActiveModel::Serializer::CollectionSerializer::CannotInferRootKeyError do serializer.json_key end end + def test_json_key_with_empty_resources_with_non_type_serializer + resource = [] + serializer = collection_serializer.new(resource, serializer: NonTypeSerializer) + assert_raise ActiveModel::Serializer::CollectionSerializer::CannotInferRootKeyError do + serializer.json_key + end + end + + def test_json_key_with_empty_resources_with_non_type_serializer_when_raise_cannot_infer_root_key_error_is_false + previous_raise_cannot_infer_root_key_error = ActiveModelSerializers.config.raise_cannot_infer_root_key_error + ActiveModelSerializers.config.raise_cannot_infer_root_key_error = false + resource = [] + serializer = collection_serializer.new(resource, serializer: NonTypeSerializer) + assert_nil serializer.json_key + ensure + ActiveModelSerializers.config.raise_cannot_infer_root_key_error = previous_raise_cannot_infer_root_key_error + end + def test_json_key_with_empty_resources_with_serializer resource = [] serializer = collection_serializer.new(resource, serializer: MessagesSerializer)