Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serializing the errors hash in ActiveModel::Serializer

I'm using ActiveModel::Serializer to customize the JSON responses for my API. This works fine in most cases, except when it fails to save a model successfully.

For example,

def create
  def create
    book = Book.new(book_params)
    book.save

    respond_with book, location: nil
  end
end

As I understand it, the respond_with action will basically execute code that looks something like this (in order to generate the response).

  if resource.errors.any?
    render json: {:status => 'failed', :errors => resource.errors}
  else
    render json: {:status => 'created', :object => resource}
  end

This does match up with what I'm seeing - if my model fails to save successfully I see the errors hash as the response. However, I can't figure out how I specify a serializer for the errors hash.

I tried defining an ErrorsSerializer and if I run

ActiveModel::Serializer.serializer_for(book.errors)

in the console it seems to find my serializer, but it doesn't get used. How do I customize the JSON response in this scenario?

like image 985
Jaco Pretorius Avatar asked Aug 24 '14 17:08

Jaco Pretorius


People also ask

What is ActiveModel serializer?

ActiveModel::Serializer At a basic level, it means that if we have a Post model, then we can also have a PostSerializer serializer, and by default, Rails will use our serializer if we simply call render json: @post in a controller.

What does a serializer do in Ruby?

Serialization converts an object in memory into a stream of bytes that can be recreated when needed. Serializers in Ruby on Rails convert a given object into a JSON format. Serializers control the particular attributes rendered when an object or model is converted into a JSON format.

What is serializer in backend?

According to Microsoft documentation: Serialization is the process of converting an object into a stream of bytes to store the object or transmit it to memory, a database or file. Its main purpose is to save the state of an object in order to be able to recreate it when needed.


1 Answers

I believe that the problem in this case is that for the failed status you won't call render with an object, like for created status.

You can use a custom Serializer when calling render, for this case you can probably use something like

if resource.errors.any?
  render serializer: ErrorSerializer, json: {:status => 'failed', :errors => resource.errors}
else
  render json: {:status => 'created', :object => resource}
end

Give it a try and keep us informed of the result :)

like image 99
Miguelgraz Avatar answered Oct 18 '22 07:10

Miguelgraz