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?
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.
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.
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.
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 :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With