将 ActiveRecord 验证错误转换为 API 可使用错误

2024-03-09

我正在 Rails 4 中编写一个非常标准的 CRUD RESTful API。不过,我在错误处理方面有所欠缺。

假设我有以下模型:

class Book < ActiveRecord::Base
  validates :title, presence: true
end

如果我尝试创建没有标题的书籍对象,我将收到以下错误:

{
  "title": [
    "can't be blank"
  ]
}

ActiveRecord 验证旨在与表单一起使用。理想情况下,我希望将每个人类可读的验证错误与 API 使用者可以使用的常量进行匹配。所以像这样:

{
  "title": [
    "can't be blank"
  ],
  "error_code": "TITLE_ERROR"
}

这都可以用于显示用户面临的错误(“标题不能为空”)并且可以在其他代码中使用(if response.error_code === TITLE_ERROR...)。 Rails 中是否有任何工具可以实现此目的?

编辑:这是一个Rails 2 天提出的非常相似的问题 https://stackoverflow.com/questions/8933864/pattern-for-translating-activerecord-validation-errors-to-api-responses.


On 错误代码.yml定义您的标准 API 错误,包括status_code, title, details和一个内部code然后,您可以在 API 文档中提供有关错误的更多信息。

这是一个基本示例:

api:
  invalid_resource:
    code: '1'
    status: '400'
    title: 'Bad Request'

not_found:
    code: '2'
    status: '404'
    title: 'Not Found'
    details: 'Resource not found.'

On 配置/初始化器/api_errors.rb将该 YAML 文件加载到常量中。

API_ERRORS = YAML.load_file(Rails.root.join('doc','error-codes.yml'))['api']

On 应用程序/控制器/关注点/error_handling.rb定义一个可重用的方法来以 JSON 格式呈现 API 错误:

module ErrorHandling
  def respond_with_error(error, invalid_resource = nil)
    error = API_ERRORS[error]
    error['details'] = invalid_resource.errors.full_messages if invalid_resource
    render json: error, status: error['status']
  end
end

在您的 API 基础控制器上包含关注点,以便它在继承它的所有控制器上可用:

include ErrorHandling

然后,您将能够在任何这些控制器上使用您的方法:

respond_with_error('not_found') # For standard API errors
respond_with_error('invalid_resource', @user) # For invalid resources

例如,在您的用户控制器上,您可能有以下内容:

def create
  if @user.save(your_api_params)
    # Do whatever your API needs to do
  else
    respond_with_error('invalid_resource', @user)
  end
end

您的 API 将输出的错误将如下所示:

# For invalid resources
{
  "code": "1",
  "status": "400",
  "title": "Bad Request",
  "details": [
    "Email format is incorrect"
  ]
}

# For standard API errors
{
  "code": "2",
  "status": "404",
  "title": "Not Found",
  "details": "Route not found."
}

随着 API 的增长,您将能够轻松地在 YAML 文件中添加新的错误代码,并通过此方法使用它们,从而避免重复并使错误代码在整个 API 中保持一致。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 ActiveRecord 验证错误转换为 API 可使用错误 的相关文章

  • Guard 不会加载 WDM

    我正在学习 Michael Hartl 的 Rails 教程 到目前为止该教程非常出色 我在高级设置一章中 他以有利于 TDD 的方式配置 Rails 环境 我安装了 Guard 并且通过运行我在 spec 文件夹中的测试 它一直正常运行
  • 查询参数和assert_generates/assert_routing - 我缺少什么?

    我想我已经介绍了使用查询参数测试路由的排列 但没有一种方法通过 在我的 paths rb 中 我有以下内容 resources items 然后对于我的功能测试我有 require ruby debug require test helpe
  • Correct_user 和 admin 的多个 before_filter 语句

    我有一个组资源 我正在尝试使用适当的授权来设置该资源 我试图实现的授权逻辑是这样的 只有群组成员才能查看他们的群组 管理员可以查看any组 以及采取其他行动 我尝试在组控制器中使用以下 before filter 语句来执行此操作 befo
  • NodeJS 路由器负载太大

    我在 Nodejs 应用程序中创建休息端点 如下所示 在我的 server js 中 我有以下代码 var express require express var app express app use express json limit
  • 指定的 sqlite3 gem 未加载

    虽然我对 Ruby on Rails 比较陌生 但我开发应用程序已经有一段时间了 我似乎遇到的问题是 当我创建一个新的 Rails 应用程序 本地 使用 c9 时 当我启动 apache 服务器时 我似乎收到此错误 Specified sq
  • 如何找到查询结果的大小

    我在 Rails 中有以下查询 records Record select y id source where source gt source y id gt y id group y id source having count 1 如
  • Trello API - 未经授权的权限请求

    我正在尝试编写一个小脚本来更新卡的当前列表中的时间量 以便我们可以优化吞吐量 我在 jsfiddle 上写了一个小脚本 几乎可以工作 但我得到了一个 请求未经授权的卡许可 当尝试使用时 Trello post cards card id a
  • Facebook API 错误 100 - 无效链接

    我正在使用 Facebook API 在我的 Rails 应用程序中创建发送对话框 我只是在 Javascript 中使用 Facebook 推荐的格式 作为 HTML 中的脚本 我的问题是我得到 API Error code 100 in
  • 尝试使用适用于 Windows XP 的 Heroku 时未找到 msvcrt-ruby18.dll

    我有一个学生在 Windows XP 上进行开发 他在尝试运行时遇到了一个奇怪的错误heroku keys add 错误是 This application has failed to start because msvcrt ruby18
  • Rails 3 默认作用域、可覆盖的作用域

    我遇到的情况是现有应用程序的行为正在发生变化 这让我非常头疼 我的应用程序有照片 照片有一个状态 batch queue or complete 应用程序中的所有现有照片都是 完整的 99 的情况下 我只需要显示完整的照片 并且在所有现有代
  • 根据客户端发送 HTML 或 JSON 响应

    我有一个带有 Eloquent 实体及其各自的 Laravel 应用程序RESTful 资源控制器 http laravel com docs 5 0 controllers restful resource controllers 如下所
  • Postgres 使用 Rails Active Record 在 IN 列表中 ORDER BY 值

    我收到按 收入 排序的 UserId 列表 一次大约 1000 个 我在 我的系统数据库 中有用户记录 但 收入 列不存在 我想从 我的系统数据库 中检索用户 按照列表中收到的排序顺序 我尝试使用 Active Record 执行以下操作
  • Mongoid - 同一外域的两个域的逆

    我试图让以下 Mongoid 关系发挥作用 但每个团队的游戏字段都是一个空数组 这不是一个有效的关系模型吗 我是否需要分开比赛 即主场比赛和客场比赛 class Team include Mongoid Document has many
  • 如何使用继承来建模 RESTful API?

    我有一个需要通过 RESTful API 公开的对象层次结构 但我不确定我的 URL 应该如何构建以及它们应该返回什么 我找不到任何最佳实践 假设我有从动物继承的狗和猫 我需要对狗和猫进行CRUD操作 我还希望能够对一般动物进行手术 我的第
  • CakePHP 3 API 的 POST 请求不起作用

    我正在使用 CakePHP 3 x 文档开发 API 为了开发这个 API 我使用了他们的官方文档 https book cakephp org 3 0 en development rest html https book cakephp
  • 在 WCF Web 编程模型中,如何编写具有一组查询字符串参数(即具有相同名称)的操作协定?

    使用 WCF Web 编程模型 可以指定一个操作契约 如下所示 OperationContract WebGet ResponseFormat WebMessageFormat Xml UriTemplate SomeRequest qs1
  • ApplicationController 的未定义方法“helper_method”,Rails 5

    我正在尝试使用doorkeeper 将oAuth2 0 集成到我的仅rails api 应用程序中 但我不断收到此错误 ApplicationController 的未定义方法 helper method 但无法找到解决该问题的明确解决方案
  • 如何在 Rails 3.2.1 版本中注释 Rails 模型

    我正在尝试遵循一些在线教程来在 Rails 中注释我的模型 然而 似乎所有教程都在谈论过时的注释版本或不正确的安装 这真是一团糟 到目前为止我已经尝试过以下方法 1 在 Gemfile 中添加此内容 gem annotate 2 4 0 2
  • 415 不支持的媒体类型; Angular2 到 API

    我是 Angular 2 的新手 我面临着一个无法找到解决方案的问题 当我尝试从 Angular 2 发布到 API 时 我得到 415 不支持的媒体类型 角度2代码 onSubmit value any console log value
  • 当一组工作人员完成时如何执行 Sidekiq 回调

    假设我有一个 Sidekiq 任务将产品处理到我的数据库 每个产品都按商店分组 因此我的代码的一个过于简化的示例将是这样的 stores each do store store products each do product Produc

随机推荐

  • 如何使用shell脚本访问mysql数据库?

    有没有办法使用 shell 脚本访问 MySQL 数据库 想要对多个表进行一些选择和插入 如果您能提供一些示例代码 那就太好了 因为我是脚本编写新手 这个链接似乎有你想要的信息 http www cyberciti biz faq usin
  • Android SQLite 中的多线程怎么样?

    在我的应用程序中 我必须实现一些 UI 和同步服务 它在后台运行并更新数据 同步服务并不是很简单 它使用了多线程 所以 这是我的故事 当我开始开发这个应用程序时 我对sqlite一无所知 所以我只是没有在Java中使用任何线程同步 结果 我
  • Qt 我可以在构造函数中将信号/槽连接到自身吗?

    编辑 与信号 插槽 连接无关 问题是构造函数调用构造函数 可能有更好的方法来做到这一点 我有兴趣听到这些 我有从 QLabel 派生的 MyClass 我想在信号中传递更多有关派生类的数据 而不是基本信号的数据 因此 我创建了一个插槽来拦截
  • 元音计数顺序

    这不是一个家庭作业问题 而是一个考试准备问题 我应该定义一个函数syllables word 计算音节数 一句话如下 元音的最大序列是一个音节 最终e在一个单词中不是一个音节 或者它是元音序列的一部分 的 我不必处理任何特殊情况 例如最终的
  • SQL - 将每个单词的第一个字母大写

    我知道这个线程到处都存在 但是 这是一个略有不同的情况 在我公司使用的套件中 我对 SQL 的访问权限有限 无法运行具有函数等的复杂代码 我有一个 SQL 查询 将多个列上的数据编译为一列 并使用 group by 子句来消除多重性 然而
  • TSQL RIGHT 字符串函数不起作用

    我无法理解为什么正确的功能不适合我 我试图在这里容纳尽可能多的输出 如果阅读起来令人困惑 我深表歉意 DECLARE Nbr VARCHAR 27 SELECT Nbr xmz nbr FROM xml temp AS xmz SELECT
  • 要显示此页面,Firefox 必须发送将重复之前执行的任何操作(例如搜索或订单确认)的信息

    嘿 我收到了 Firefox 的确认 To display this page Firefox must send information that will repeat any action such as a search or or
  • Cargo 是否可以在不构建应用程序的情况下下载并构建依赖项?

    有没有办法告诉Cargo http doc crates io guide html安装和构建我的所有依赖项 但不尝试构建我的应用程序 我想cargo install会这样做 但实际上它也一直用于构建我的应用程序 我想要达到一个状态carg
  • 如何从 Google Assistant 接收答案作为字符串,而不是音频流

    我正在使用 Assistant SDK 中的 python 库通过 gRPC 进行语音识别 我已识别语音并以调用该方法的字符串形式返回resp result spoken request text from googlesamples as
  • 检测 Skype 是否处于“紧凑视图”或“默认视图”

    我的应用程序的运行方式由 Skype 的视图模式决定 因为我的应用程序正在寻找类窗口TConversationWindow 如果在默认视图中 它是tSkMainForm 如果在紧凑视图中 它不是tSkMainForm 这是我尝试做的 Fun
  • 尝试将 std::pair 插入 std::set

    我无法理解这段代码中的错误是什么 include
  • 我应该将哪个会话库与 CodeIgniter 一起使用?

    我最近开始使用 CI 及其 CI 会话 但我注意到 使用 CI 会话比使用基本 PHP 会话特别耗时得多 Arrays 我有一组数据 无论登录 注销如何 它都会持续存在 称为 SESSION stats 然后我以以下形式将数据存储在该数组中
  • 如何禁用 RabbitMQ 默认 tcp 监听端口 - 5672

    我已经配置了RabbitMQrabbitmq config具有新端口号的文件 即带有 SSL 的 5671 现在我想禁用默认端口 即 5672 配置文件如下 rabbit ssl listeners 5671 ssl options cac
  • C++ 相当于指定初始化器?

    最近我一直在研究一些嵌入式设备 其中我们有一些结构体和联合体需要在编译时初始化 以便我们可以将某些不需要修改的东西保留在闪存或ROM中 并节省一点闪存或 SRAM 但会牺牲一点性能 目前 该代码编译为有效的 C99 但如果没有这种调整 它也
  • Prolog 中的条件编写

    I have Prolog包含飞机时刻表的数据库 它看起来是这样的 fly id from to days 1 0 1 0 1 0 1 正如你所看到的 有 7 个值days谓词 从星期一到星期日 我想做的是每天打印 价值所在1 但将其打印为
  • Win32:Watson 博士的完整/迷你转储和我自己编写的转储之间有区别吗?

    我有一个应用程序在发布版本中偶尔会崩溃 不幸的是 看起来它在第 3 方 DLL 中崩溃了 在试图掌握它的过程中 我一直在如何操作和 Windows 如何创建故障转储的描述的海洋中游泳 我正在考虑使用这个建议的小型转储 获取启动时崩溃的进程的
  • 具有相同擦除的两种方法不需要覆盖等效(或者它们的签名不是它们之间的子签名)?

    我正在阅读关于 jdk6 的令人难以置信的书 java scjp 认证程序员指南 其中有一个关于泛型覆盖的部分 它描述了子签名和覆盖等效项 并描述了我引用的一些覆盖等效项的示例 给定类中的以下三个泛型方法声明 static
  • 无法保存 applicationHost.config 文件

    我无法保存 applicationHost config 文件 当我停止 IIS 服务并关闭 Visual Studio 时 它显示 保存失败 它在另一个程序中打开 知道吗 如果您使用 64 位架构并尝试使用 32 位编辑器 例如 Note
  • 将背景图像添加到各个片段

    我有一个应用程序有多个fragments我想知道如何添加每个不同的背景fragment 我使用的布局有可滚动选项卡 它们都使用相同的 xml 文件 我也有一个MainActivity设置视图和adapter对于每个fragment 我知道你
  • 将 ActiveRecord 验证错误转换为 API 可使用错误

    我正在 Rails 4 中编写一个非常标准的 CRUD RESTful API 不过 我在错误处理方面有所欠缺 假设我有以下模型 class Book lt ActiveRecord Base validates title presenc