2017 年 4 月 27 日,星期四

Rails 5.1:爱上 JavaScript,系统测试,加密秘钥等等

作者:dhh

为了庆祝本周在亚利桑那州菲尼克斯举行的第 12 届 RailsConf,我们自豪地宣布 Rails 5.1 已正式准备就绪!自 Rails 5.0 以来,我们已进行了 超过 4100 次提交,让一切都变得更加简单、轻松,还有点有趣?(这是 RailsConf 上的笑话)

亮点自第一个测试版起就没有真正改变,但这里再重复一下

爱上 JavaScript

多年来,我们和 JavaScript 的关系一直很难相处,甚至还产生过争论。但现在这一切都成为过去了。近些年来,JavaScript 获得了极大的改进,尤其是随着 ES6 的出现,以及纱线和 webpack 等打包和编译工具的出现。Rails 对这两个解决方案欣然接受,既往不咎。

除了生态系统管理,JavaScript 和 Ruby 在语言设计上有着深刻的哲学羁绊。让我们集中精力研究我们共同的方面,并借助一些关键指导公约帮助 Rails 程序从 JavaScript 中提取最佳部分。

Rails 5.1 的改进集中在三个主要的方面

  1. 通过纱线从 NPM 管理 JavaScript 依赖项。可以将 纱线 视为 JavaScript 版的 Bundler(它甚至包含 Yehuda Katz!)这使得依赖于 React 等库或 NPM 中的任何其他内容变得十分容易。您通过纱线依赖的所有内容都可以按需在资源管道中提供,就像供应商依赖项一样。只需使用 binstub bin/yarn 即可添加依存项。

  2. 可以选择使用 webpack 编译 JavaScript。虽然有数百万种不同的模块构建器/编译器可用于 JavaScript,但 webpack 正迅速成为首选。我们已经通过 Webpacker 新 Gem 使得可以通过 Rails 轻松使用 webpack,您可以使用 --webpack (或者甚至使用 --webpack=react --webpack=angular --webpack=vue )针对新的项目自动配置。这与资源管道完全兼容,您可以继续将资源管道用于图像、字体、声音等内容。您甚至可以在资源管道中放置一些 JavaScript,并通过 webpack 处理一些 JavaScript。所有这些都可以通过默认启用的纱线进行管理。

  3. 将 jQuery 设为默认依赖项。以前我们要求 jQuery 来提供诸如 data-remote、data-confirm 以及 Rails UJS 其他部分等功能。随着我们 重写 rails-ujs 以使用原生 JavaScript,这种依赖项不再必要。当然,您仍然可以自由使用 jQuery,但不再是一定要使用它了。

感谢 Liceth Ovalles 对 Yarn 集成的贡献,感谢 Dangyi Liu 对 rails-ujs 的贡献,感谢 Guillermo Iguaran 对整个项目的全面指导!

系统测试

2014 年 RailsConf 的主题演讲 中,我详细讲述了过于注重单元测试(和 TDD)让我们误入歧途。虽然单元测试也是一个完整测试解决方案的一部分,但它并不是最重要的部分。从控制器到模型再到视图,验证行为的集成测试应该发挥更大的作用。Rails 已为集成测试提供了一个非常棒的内置解决方案。

但是,如果系统依赖于 JavaScript,集成测试无法帮助你测试整个系统。而当今大多数主要 Web 系统都至少在一定程度上依赖 JavaScript。这就是由真实浏览器驱动的系统测试发挥作用的地方。

对于此类系统测试,Ruby 中一直有一个名为 Capybara 的解决方案。但为 Rails 正确配置 Capybara 一直是一个需要探索的过程。于是现在,我们已 将其直接集成到框架中!你获得了一个专为 Chrome 预配置的 Capybara 的精美封装,还进行了增强,可以通过 Action Dispatch 提供失败屏幕截图。你也不用再担心其他 数据库清理策略了,因为内置的事务性测试现已回滚系统测试更改。

这些测试也并非没有取舍。通过整个浏览器设置来进行测试当然仍然比使用模拟数据库来测试模型要慢。但它还测试了许多其他内容。你最好熟悉系统测试,并将其作为测试解决方案的一部分。

感谢 Eileen M. UchitelleBasecamp 中提取了这段内容!

加密密钥

如果你将未加密的生产密码、API 密钥和其他密钥检入版本控制系统,你的做法是错误的。这是不安全的,你应该立即停止!以上说法写起来容易,但如果不提供明确的使用建议,那也不会有多大帮助。

人们一直使用 ENV 来存储这些密钥,或者使用各种其他解决方案。ENV 模型有很多取舍和缺点,最重要的是,你仍然需要将这些密钥存储在其他实际位置。

受到 Ara T. Howardsekrets gem 的启发,我们已 将加密密钥管理功能内置到 Rails 5.1 中。你可以使用 bin/rails secrets:setup 设置一个新的加密密钥文件。系统会生成一个主密钥,你可以将其存储在储存库外部,但允许你将实际生产密钥提交到版本控制中。这些密钥随后通过注入的密钥文件或 ENV 中的 RAILS_MASTER_KEY 在生产环境中进行解密。

感谢 Kasper Timm Hansen 为此事项所做出的工作,以及感谢 Ara 提供的灵感!

参数化邮件

Action Mailer 仿照 Action Controller 建模。它通过抽象控制器共享基础,但它长期以来在动作之间共享逻辑的方式上存在一个缺点。

在 Action Controller 中,通常使用 before_action 和类似的回调来提取适用于多个动作的逻辑。之所以这样做是因为,在调用动作之前,即可使用 params 哈希。但在 Action Mailer 中,我们一直使用具有显式参数的常规方法签名,因此在动作运行之前,过滤器无法使用这些参数。

使用 参数化邮件,我们现在让你可以选择使用参数调用邮件,这些参数与控制器中的参数类似,可以在调用动作之前使用。结合默认的 to/from/reply_to 标头,极大地简化了一些邮件动作。

它完全向后兼容,并且你可以先转换那些最需要进行提取的邮件。

直接路由和已解析的路由

我们有一个可爱、简单的 API,可用于声明新的资源路由。但是,如果你想要添加新的程序化路由,其逻辑根据参数来确定最终目标,那么,你必须在使用帮助程序和其他混乱的方法的情况下自己划船。

使用定向路由,你现在可以声明程序化路由,这些路由拥有 Ruby 的全部功能,能够根据传递的参数执行不同的操作。

使用已解析的路由,你可以直接为模型重新编程多态查找,以使用兼容的方法。因此,这允许你将 link_to @comment 变成类似于 message_path(@comment.parent, anchor: "comment_#{@comment.id}")的最终路由。

感谢 Andrew White 使这一切成为可能

使用 form_with 统一 form_tag/form_for

长期以来,我们一直拥有两种并行结构来创建表单。一种是通过 form_for 使用记录的,其中我们使用约定优先于配置来提取详细信息,另一种是使用 form_tag 手动配置的。现在,我们已经使用 form_with 统一了这两个层次结构。一个单一的根树,你可以通过一个推断的记录或手动来配置。它漂亮多了,也简单多了。

感谢 Kasper Timm Hansen 也为此事项做出了贡献!

其他一切

除了重点部分之外,我们还对所有框架进行了数百项其他修复和改进。请仔细阅读 CHANGELOG 以了解所有好东西

您可在 版本说明 中找到对高级别变更内容的精彩总结。

Rails 5.1 的发行经理是 Rafael França

根据我们的 维护策略,Rails 5.1 的发行意味着:仅对 5.1.x 提供漏洞修复、对 5.1.x 和 5.0.x 提供常规安全问题修复,对 5.1.x、5.0.x 和 4.2.x 提供严重的安全问题修复。这意味着 4.x 及以下版本实际上将不再受支持!

感谢社区中每一位辛勤测试 Rails 5.1 Beta 版和 Release Candidate 版的人员!我们通过此过程修复了 600 多次提交之后的漏洞报告和提出的问题。谢谢!Gracias!Merci!TAK!