active_model_serializers icon indicating copy to clipboard operation
active_model_serializers copied to clipboard

Specify root key fail when collection is empty

Open ghost opened this issue 8 years ago • 8 comments

Expected behavior vs actual behavior

class Simpeg::JabatanSerializer < ActiveModel::Serializer
	type :data
end

I specify the root key with 'data'. But that not work when collection is empty. The root name back to 'simpeg/jabatans'.

Steps to reproduce

class Simpeg::JabatanController < ApplicationController
	def index
		data = Simpeg::Jabatan.where(judul: 'nothing')
		render json: data
	end
end

Environment

ActiveModelSerializers Version 0.10.4 Rails Version 5.0.2 ruby 2.2.6p396 (2016-11-15 revision 56800) [x86_64-linux]

Backtrace

(e.g., provide any applicable backtraces from your application)

Additonal helpful information

ActiveModel::Serializer.config.adapter = :json

ghost avatar Mar 24 '17 17:03 ghost

@wirasto Thanks for the bug report. The JSON adapter uses the json_key method which is

    # Used by adapter as resource root.
    def json_key
      root || _type || object.class.model_name.to_s.underscore
    end

Can you try seeing what the value of Simpeg::JabatanSerializer.new(Simpeg::Jabatan.where(judul: 'nothing')).json_key is?

bf4 avatar Mar 28 '17 07:03 bf4

The value is data

ghost avatar Mar 29 '17 17:03 ghost

@wirasto

The value is data

A little help here.. can you describe the data?

bf4 avatar Mar 29 '17 18:03 bf4

I specify the root key with 'data'. So the result value is 'data'

ghost avatar Mar 29 '17 18:03 ghost

Oh, ok. so you're expecting

 { "data" : [] }

and getting

{ "simpeg/jabatans" : [] }

?

Is your collection actually an empty array? If so, see https://github.com/rails-api/active_model_serializers/blob/v0.10.5/lib/active_model/serializer/collection_serializer.rb#L30-L50 Given an empty array and no explicit serializer, AMS has no idea to know what 'type' of empty array it is...

bf4 avatar Mar 29 '17 19:03 bf4

I'm guessing that the issue is in step

  # 3. get from collection name, if a named collection
  key ||= object.respond_to?(:name) ? object.name && object.name.underscore : nil

where you want to lookup the serializer from the empty collection, but we just get the collection name. I suppose we could add a condition that tries to look up the serializer for the object.name, when present.

bf4 avatar Mar 29 '17 19:03 bf4

This would be addressed by something like https://github.com/rails-api/active_model_serializers/pull/1867

bf4 avatar Apr 12 '17 14:04 bf4

This issue still valid. With

  def json_key
    'data'
  end

in my serialiser base class, it returns all data with the root key data when there is data, but returns other key when the list of objects to serialise is empty. Expected behaviour would be {"data": []}

Here's a failing test of my use case: https://github.com/rails-api/active_model_serializers/commit/6e46e673431f1d732d84a63571f2a8c46fd870d7

sergioisidoro avatar Sep 23 '22 08:09 sergioisidoro