在rails 中对返回的json 进行 错误处理

原文来自于 http://travisjeffery.com/b/2012/04/rendering-errors-in-json-with-rails/


Having seen a lot of bad practices when it comes to handling and rendering errors in JSON, bad practices such as misusing HTTP statuses, success/error callbacks, and making building error messages harder than necessary, here are bad and good practices.

Here’s an example that is bad,

JavaScript,

$.ajax(
  // ...
    dataType: "json"
  , success: function(data){
    if (data.errors) {
      // do something with errors
    } else {
      // do something with successful data
    }
  }
)

Controller,

def create
  @model = Model.create(params[:model])
  if @model.save
    render :json => @model.to_json
  else
    render :json => { :errors => @model.errors.full_messages }
  end
end

The biggest concern in the example above is that we’re not using HTTP statuses as they were intended which is bad both practically and semantically.

Semantically in the sense that with this implementation we have to mix error handling in a success callback. Practically since our browser and libraries can work together to extract the switch logic.

This is a good example,

JavaScript,

$.ajax({
  // ...
    dataType: "json"
  , success: function(data){
      // do something with successful data
  }
  , error: function(xhr){
      var errors = $.parseJSON(xhr.responseText).errors
      // do something with errors
  }
})

Controller:

def create
  @model = Model.create(params[:model])
  if @model.save
    render :json => @model
  else
    render :json => { :errors => @model.errors.full_messages }, :status => 422 and return
  end
end

注意这里的 :status => 422 方法,是使得返回的response 的状态是 422。这样ajax中就可以调用到error的回调方法。而不需要像笨办法里面的那种在success方法里面进行判断。

and return 语法是rails 中的语法,使的当前渲染后,直接退出这个方法。

With an HTTP error status (e.g. 422 unprocessable entity) our error callback is called for us, our code is more declarative and without unnecessary logic.

Another small nit-pick is that we’re now letting Rails serialize our data according to our response type, i.e. it will call to_json for us.

Another tip is to use full_messages rather than serializing the errors object as it is,

render :json => { :errors => @model.errors }

The above will present the errors in a hash where the keys are attributes and the values are errors,

# => { name: ["is blank"], age: ["is not greater than 0"]}
render :json => { :errors => @model.errors.full_messages }

full_messages on the other hand will return an array of full messages,

# => ["Name is blank", "Age is not greater than 0"]

I once watched a Rails/Backbone screencast where the author serialized the errors object as is and spent ~30 mins manipulating the data client-side into exactly what full_messages returned.

This is much easier to work with and I have never once needed the data given by serializing model.errors.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值