【问题标题】:How To Render Correct JSON format with raised error如何呈现正确的 JSON 格式并引发错误
【发布时间】:2016-02-15 17:41:12
【问题描述】:

我确定我在这里有一个基本的rescue_from 问题,但是当我的Validation 失败但我似乎无法弄清楚时引发异常时,我试图获得所需的输出。

目前我的ApplicationController如下:

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

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

end

我得到的 JSON 输出是:

    {
  "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"
}

我想要得到的(或类似的)输出如下:

    {
  "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"
  ]
}

我不知道如何得到这个。当我注释掉ApplicationController 中的rescue_from 方法并像这样设置我的RecordController 创建方法时,我得到了所需的输出:

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

虽然这是我想要的,但我必须去每个控制器并添加它,但这不是 DRY 方法...我宁愿将它集中在 ApplicationController

感谢任何帮助。 谢谢!

我已经检查了Correct JSON format & How can I “Pretty” format my JSON output in Ruby on Rails?

【问题讨论】:

    标签: ruby json ruby-on-rails-4


    【解决方案1】:

    只是一个更新,接受的答案不是 JSON-API 错误规范。

    查看上面的链接规范,因为错误对象可以返回几个不同的键

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

    【讨论】:

      【解决方案2】:

      经过更多研究,我想通了。

      rescue_from 正文中的异常对象 e 具有带有导致异常的记录的 record 属性,您可以使用该记录的 errors 属性提取错误并使用您的格式创建响应想要:

      我将ApplicationController 中的这一行编辑为:

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

      RecordController创建方法更改为:

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

      这将给出输出:

       {
        "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"
            ]
          }
        }
      }
      

      如果您提出了其他要呈现示例的异常,这真的很有帮助:

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

      如果我搜索无效记录44,它将呈现:

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

      我希望这个答案对其他人有所帮助!干杯

      【讨论】:

        【解决方案3】:

        你可以这样做:

        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
        

        如果返回错误,它将返回:

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

        与您展示的第一个示例相关,ruby 的 Exception#message http://ruby-doc.org/core-2.2.0/Exception.html#method-i-message 以您描述的方式返回错误。我通常看到 rescue_from 用于返回通用 404 页面。

        希望对你有帮助

        【讨论】:

        • 我试图阻止自己向每个控制器和操作添加代码。用你的方法,我必须这样做。这就是我只想将代码添加到ApplicationController 的原因
        • 是的,如果不尝试解析异常消息,我不确定您将如何获得与对象本身返回的相同格式。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-05-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多