Search code examples
ruby-on-railsactive-model-serializers

How to fix an 'ArgumentError: Cannot infer root key from collection type. Please specify the root or each_serializer option, or render a JSON String'


I'm passing an object to a serializer which return's all the records,when object returns empty array is the time where this error will show up.

def booked_cars
     if params["id"].present?
        @customer = Customer.find(params["id"].to_i)
        @booked_cars = @customer.bookings.where(cancelled: false).collect{|c| c.used_car}
        render json: @booked_cars, each_serializer: UsedCarSerializer
      end
end

I expect it to give array of objects or an empty array,instead gives an argument error (ArgumentError (Cannot infer root key from collection type. Please specify the root or each_serializer option, or render a JSON String):)


Solution

  • Try adding serializer option or root option as specified in the error response from active_model_serializer.

    Because the serializer gets the root from the collection.

    @customer = Customer.find(params["id"].to_i)
    render json: @customer
    

    In the above case, the serializer will respond like the below,

    { 
     "customer": #root
      {
       # attributes ...
      }
    }
    

    because the object is not a collection, so the root is in singular form(customer).

    @customers = Customer.where(id: ids) # ids is an array of ids.
    render json: @customer
    

    In the above case, the serializer will respond like the below,

    { 
     "customers": #root
      {
       # attributes ...
      }
    }
    

    because the object is not a collection, so the root is in plural form(customers).

    The serializer will add root based on the class of the object(ActiveRecord || ActiveRecordCollection).

    If the object is empty array serializer can't predict which to use as a root. So we need to specify the root or serializer option.

    render json: @customer, root: 'customer'
    

    or

     render json: @customer, serializer: UsedCarSerializer
    

    NOTE: Active model serializer detect the serializer either from the class of the object or from the serializer option.