呈现带有属性和完整错误消息的ActiveRecord验证错误



这是一个简单的控制器更新操作:

def update
note = Note.find(params[:id])
if note.update(note_params)
render json: note.to_json
else
render json: {errors: note.errors}, status: :unprocessable_entity
end
end

这会在表单中显示错误{"errors":{"title":["can't be blank"]}}

,但我希望它的形式是{"errors":{"title":["Title can't be blank"]}}

简单使用{errors: note.errors.full_messages}给了{:errors=>["Title can't be blank"]}和缺少属性键。

我能把它变成想要的形式的唯一方法似乎有点复杂:

full_messages_with_keys = note.errors.keys.inject({}) do |hash, key|
hash[key] = note.errors.full_messages_for(key)
hash
end
render json: {errors: full_messages_with_keys}, status: :unprocessable_entity

这可以工作,但是我必须这样做似乎很奇怪,因为它似乎是在SPA前端进行验证的一个非常常见的用例。是否有一个内置的方法/更规范的方式?

您可以使用ActiveModel::Errors#group_by_attribute来获取每个键的错误散列:

person.errors.group_by_attribute
# => {:name=>[<#ActiveModel::Error>, <#ActiveModel::Error>]}

从那里简单地从每个ActiveModel::Error实例生成完整的消息:

note.errors
.group_by_attribute
.transform_values { |errors| errors.map(&:full_message) }

是否有一个内置的方法/更规范的方式?

没有。一个框架不可能涵盖所有可能的需求。它提供了格式化错误所需的工具。

但是,如果你想要疯狂的话,可以将此功能推入模型层,序列化器甚至monkeypatched到ActiveModel::Errors上,而不是在你的控制器上重复这个功能。

class ApplicationRecord < ActiveRecord::Base
def grouped_errors
errors.group_by_attribute
.transform_values { |errors| errors.map(&:full_message) }
end
end

相关内容

  • 没有找到相关文章

最新更新