How To Render Correct JSON format with raised error

I'm sure I have a basic rescue_from question here but, I am trying to get a desired output when an exception is raised when my Validation fails but I can't seem to figure it out.

Currently my ApplicationController is as follows:

class ApplicationController < ActionController::API
  include ActionController::Serialization

  rescue_from ActiveRecord::RecordInvalid do |e|
  render json: {error: e.message}, status: 404
  end  

end

and the JSON output I get is:

    {
  "error": "Validation failed: Organization can't be blank, Description can't be blank, Artwork can't be blank, Language code can't be blank, Copyright can't be blank, Right to left is not included in     the list, Digital audio is not included in the list, Portion is not included in the list, Electronic text is not included in the list, Old is not included in the list, New is not included in the list"
}

The desired ouput I would like to get (or something similar) is as follows:

    {
  "organization_id": [
    "can't be blank"
  ],
  "description": [
    "can't be blank"
  ],
  "artwork": [
    "can't be blank"
  ],
  "language_code": [
    "can't be blank"
  ],
  "copyright": [
    "can't be blank"
  ],
  "right_to_left": [
    "is not included in the list"
  ],
  "digital_audio": [
    "is not included in the list"
  ],
  "portion": [
    "is not included in the list"
  ],
  "electronic_text": [
    "is not included in the list"
  ],
  "old": [
    "is not included in the list"
  ],
  "new": [
    "is not included in the list"
  ]
}

I am not sure how to get this. I get the desired output when I comment out the rescue_from method in the ApplicationController and set the my RecordController create method like this:

  def create
    r = Record.create(record_params)
    r.save
    if r.save
    render json: r
    else
      render json: r.errors
    end
  end

Although this is what I want, I would have to go to every controller and add this but this would not be a DRY method... I would rather centralize this in the ApplicationController

Any help is appreciated. Thanks!

I have checked Correct JSON format & How can I “Pretty” format my JSON output in Ruby on Rails?


You could do it this way:

def create
  r = Record.create(record_params)
  if r.save
    render json: r.to_json
  else
    render json: errors: r.errors, status: 422
  end
end

If and error is returned, it will return this:

{
  errors:
    {
      attr_1:["can't be blank"],
      attr_2:["can't be blank"]
    }
}

Related to the first example you showed, ruby's Exception#message http://ruby-doc.org/core-2.2.0/Exception.html#method-i-message returns the errors in the way you described. I generally see rescue_from being used to return generic 404 pages.

Hope this helps


Just an update, the accepted answer is not the JSON-API specification for errors.

View the linked spec above as there are a few different keys that can be returned with the error object

{
 "error": {
    "title": "RecordNotFound",
    "detail": "Record not found for id: 44. Maybe deleted?"
  }
}

I figured it out after more research.

The exception object e in that rescue_from body has a record attribute with the record that caused the exception, you can use the errors attribute of that record to extract the errors and create a response with the format you want:

I edited this line in ApplicationController to:

rescue_from ActiveRecord::RecordInvalid do |e|
  render json: {error: {RecordInvalid: e.record.errors}}, status: 406
end

Change RecordController create method to:

def create
    r = Record.create!(record_params)
    render json: r
end

Which will give the output:

 {
  "error": {
    "RecordInvalid": {
      "organization_id": [
        "can't be blank"
      ],
      "name": [
        "can't be blank"
      ],
      "description": [
        "can't be blank"
      ],
      "artwork": [
        "can't be blank"
      ],
      "language_code": [
        "can't be blank"
      ],
      "copyright": [
        "can't be blank"
      ],
      "right_to_left": [
        "is not included in the list"
      ],
      "digital_audio": [
        "is not included in the list"
      ],
      "portion": [
        "is not included in the list"
      ],
      "electronic_text": [
        "is not included in the list"
      ],
      "old": [
        "is not included in the list"
      ],
      "new": [
        "is not included in the list"
      ]
    }
  }
}

This really helps if you have other exceptions raised you would like to render exemple:

rescue_from ActiveRecord::RecordNotFound do
  render json: {error: {RecordNotFound: "Record not found for id: #{params[:id]}. Maybe deleted?"}}, status: 404    
end 

with this if I search an invalid record 44 it will render:

{
 "error": {
    "RecordNotFound": "Record not found for id: 44. Maybe deleted?"
  }
}

I hope this answer helps others! cheers

链接地址: http://www.djcxy.com/p/47164.html

上一篇: 在Ruby中打印打印JSON

下一篇: 如何呈现正确的JSON格式,并引发错误