[英]Serializing the errors hash in ActiveModel::Serializer
我正在使用ActiveModel :: Serializer来自定义我的API的JSON响应。 这在大多数情况下都可以正常工作,除非它无法成功保存模型。
例如,
def create
def create
book = Book.new(book_params)
book.save
respond_with book, location: nil
end
end
据我了解,respond_with动作基本上会执行看起来像这样的代码(为了生成响应)。
if resource.errors.any?
render json: {:status => 'failed', :errors => resource.errors}
else
render json: {:status => 'created', :object => resource}
end
这与我所看到的相符 - 如果我的模型无法成功保存,我会将错误哈希视为响应。 但是,我无法弄清楚如何为错误哈希指定序列化程序。
我尝试定义一个ErrorsSerializer,如果我运行
ActiveModel::Serializer.serializer_for(book.errors)
在控制台中,它似乎找到了我的序列化程序,但它没有得到使用。 如何在此方案中自定义JSON响应?
我在这篇博文中找到了这个答案......就这样开始......
Rails中错误状态的默认序列化可能不是您想要的应用程序。 在这种情况下,了解如何根据需要编写自定义序列化格式是值得的。 在我的情况下,我试图匹配JSON API格式的错误 。 这是一个潜在的实施......
示例验证错误
默认情况下,Rails 4将返回一个类似于此的错误序列化(对于应始终存在title
的书籍模型):
{
"title": [
"can't be blank"
]
}
创建自定义错误序列化程序
在/serializers/error_serializer.rb
...
module ErrorSerializer
def self.serialize(errors)
return if errors.nil?
json = {}
new_hash = errors.to_hash(true).map do |k, v|
v.map do |msg|
{ id: k, title: msg }
end
end.flatten
json[:errors] = new_hash
json
end
end
在控制器中使用它
现在在控制器中include ErrorSerializer
,这样你就可以使用错误哈希来做这样的事情,即render: json: ErrorSerializer.serialize(book.errors)
结果
{
"errors": [
{
"id": "title",
"title": "Title can't be blank"
}
]
}
阅读deets的实际帖子。
我相信在这种情况下的问题是,对于failed
状态,您不会使用对象调用render
,例如created
状态。
您可以在调用render
时使用自定义Serializer,对于这种情况,您可以使用类似的东西
if resource.errors.any?
render serializer: ErrorSerializer, json: {:status => 'failed', :errors => resource.errors}
else
render json: {:status => 'created', :object => resource}
end
试一试,告诉我们结果:)
由于响应者如何为错误创建json响应, ErrorsSerializer
不起作用:
def json_resource_errors
{ errors: resource.errors }
end
(对于较新的rails,rails <4.2 https://github.com/rails/rails/blob/4-1-stable/actionpack/lib/action_controller/metal/responder.rb#L290 ,响应者已被解压缩到https:// github.com/plataformatec/responders/blob/master/lib/action_controller/responder.rb#L288 )
处理此问题的一种方法是为响应者覆盖此方法。 将此代码放在配置初始值设定项中:
# config/initializers/action_controller_responder.rb
module ActionController
class Responder
def json_resource_errors
resource.errors
end
end
end
然后您的序列化程序将解决资源错误。
resource.errors的类名是ActiveModel::Errors
因此您必须将类定义为ActiveModel::ErrorsSerializer
。
参考: 源代码
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.