Сериализация хэша ошибок в ActiveModel:: Сериализатор
Я использую ActiveModel:: Serializer для настройки ответов JSON для моего API. Это прекрасно работает в большинстве случаев, за исключением случаев, когда он не смог успешно сохранить модель.
Например,
def create
def create
book = Book.new(book_params)
book.save
respond_with book, location: nil
end
end
Как я понимаю, действие response_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 в этом сценарии?
Ответы
Ответ 1
Я считаю, что проблема в этом случае заключается в том, что для статуса failed
вы не вызываете render
с объектом, как для статуса created
.
Вы можете использовать пользовательский Сериализатор при вызове render
, для этого случая вы, вероятно, можете использовать что-то вроде
if resource.errors.any?
render serializer: ErrorSerializer, json: {:status => 'failed', :errors => resource.errors}
else
render json: {:status => 'created', :object => resource}
end
Попробуйте и сообщите нам о результатах:)
Ответ 2
ErrorsSerializer
не работает из-за того, как ответчики создают ответ json для ошибок:
def json_resource_errors
{ errors: resource.errors }
end
(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
Затем ваш сериализатор будет работать для ошибок ресурсов.
Ответ 3
Я нашел этот ответ на этом сообщении в блоге... который начинается как таковой...
Стандартная сериализация состояний ошибок в 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.
Ответ 4
Имя класса resource.errors ActiveModel::Errors
, поэтому вы должны определить свой класс как
ActiveModel::ErrorsSerializer
.
Ссылка: исходный код