更多内容请访问 rubyonrails.org:

Ruby on Rails 4.1 版本说明

Rails 4.1 中的亮点

  • Spring 应用程序预加载器
  • config/secrets.yml
  • Action Pack 变体
  • Action Mailer 预览

这些版本说明仅涵盖主要更改。要了解各种错误修复和更改,请参阅更改日志或查看 GitHub 上主要 Rails 存储库中的 提交列表

1 升级到 Rails 4.1

如果你正在升级现有的应用程序,在开始之前拥有良好的测试覆盖率是一个好主意。你还应该先升级到 Rails 4.0(如果你还没有升级),并确保你的应用程序在尝试更新到 Rails 4.1 之前仍然按预期运行。在升级时需要注意的事项列表在 升级 Ruby on Rails 指南中提供。

2 主要功能

2.1 Spring 应用程序预加载器

Spring 是一个 Rails 应用程序预加载器。它通过在后台保持应用程序运行来加快开发速度,因此你无需在每次运行测试、rake 任务或迁移时都启动它。

新的 Rails 4.1 应用程序将附带“Spring 化”的 binstubs。这意味着 bin/railsbin/rake 将自动利用预加载的 Spring 环境。

运行 rake 任务

$ bin/rake test:models

运行 Rails 命令

$ bin/rails console

Spring 自省

$ bin/spring status
Spring is running:

 1182 spring server | my_app | started 29 mins ago
 3656 spring app    | my_app | started 23 secs ago | test mode
 3746 spring app    | my_app | started 10 secs ago | development mode

查看 Spring README 以查看所有可用的功能。

请参阅 升级 Ruby on Rails 指南,了解如何迁移现有应用程序以使用此功能。

2.2 config/secrets.yml

Rails 4.1 在 config 文件夹中生成一个新的 secrets.yml 文件。默认情况下,此文件包含应用程序的 secret_key_base,但它也可以用于存储其他机密,例如外部 API 的访问密钥。

添加到此文件中的机密可以通过 Rails.application.secrets 访问。例如,对于以下 config/secrets.yml

development:
  secret_key_base: 3b7cd727ee24e8444053437c36cc66c3
  some_api_key: SOMEKEY

Rails.application.secrets.some_api_key 在开发环境中返回 SOMEKEY

请参阅 升级 Ruby on Rails 指南,了解如何迁移现有应用程序以使用此功能。

2.3 Action Pack 变体

我们通常希望为手机、平板电脑和台式机浏览器渲染不同的 HTML/JSON/XML 模板。变体使这变得容易。

请求变体是请求格式的专门化,例如 :tablet:phone:desktop

你可以在 before_action 中设置变体

request.variant = :tablet if request.user_agent =~ /iPad/

像你对格式一样响应操作中的变体

respond_to do |format|
  format.html do |html|
    html.tablet # renders app/views/projects/show.html+tablet.erb
    html.phone { extra_setup; render ... }
  end
end

为每种格式和变体提供单独的模板

app/views/projects/show.html.erb
app/views/projects/show.html+tablet.erb
app/views/projects/show.html+phone.erb

你也可以使用内联语法简化变体定义

respond_to do |format|
  format.js         { render "trash" }
  format.html.phone { redirect_to progress_path }
  format.html.none  { render "trash" }
end

2.4 Action Mailer 预览

Action Mailer 预览提供了一种方法,可以通过访问一个特殊的 URL 来查看电子邮件的外观,该 URL 会渲染它们。

你实现一个预览类,其方法返回你想要检查的邮件对象

class NotifierPreview < ActionMailer::Preview
  def welcome
    Notifier.welcome(User.first)
  end
end

预览在 https://127.0.0.1:3000/rails/mailers/notifier/welcome 中可用,在 https://127.0.0.1:3000/rails/mailers 中可用其列表。

默认情况下,这些预览类位于 test/mailers/previews 中。这可以使用 preview_path 选项进行配置。

请参阅其 文档 以获取详细的说明。

2.5 Active Record 枚举

声明一个枚举属性,其中值映射到数据库中的整数,但可以通过名称进行查询。

class Conversation < ActiveRecord::Base
  enum status: [ :active, :archived ]
end

conversation.archived!
conversation.active? # => false
conversation.status  # => "archived"

Conversation.archived # => Relation for all archived Conversations

Conversation.statuses # => { "active" => 0, "archived" => 1 }

请参阅其 文档 以获取详细的说明。

2.6 消息验证器

消息验证器可用于生成和验证签名消息。这对于安全地传输敏感数据(如记住我的令牌和朋友)很有用。

方法 Rails.application.message_verifier 返回一个新的消息验证器,该验证器使用从 secret_key_base 和给定的消息验证器名称派生的密钥对消息进行签名

signed_token = Rails.application.message_verifier(:remember_me).generate(token)
Rails.application.message_verifier(:remember_me).verify(signed_token) # => token

Rails.application.message_verifier(:remember_me).verify(tampered_token)
# raises ActiveSupport::MessageVerifier::InvalidSignature

2.7 Module#concerning

一种自然、低仪式的方式来分离类内的职责

class Todo < ActiveRecord::Base
  concerning :EventTracking do
    included do
      has_many :events
    end

    def latest_event
      # ...
    end

    private
      def some_internal_method
        # ...
      end
  end
end

此示例等同于在类内定义 EventTracking 模块,用 ActiveSupport::Concern 扩展它,然后将它混合到 Todo 类中。

请参阅其 文档 以获取详细的说明和预期用例。

2.8 来自远程 <script> 标签的 CSRF 保护

跨站点请求伪造 (CSRF) 保护现在也涵盖了带有 JavaScript 响应的 GET 请求。这可以防止第三方网站引用你的 JavaScript URL 并尝试运行它以提取敏感数据。

这意味着你的任何命中 .js URL 的测试现在都会失败 CSRF 保护,除非它们使用 xhr。升级你的测试以明确地期望 XmlHttpRequests。不要使用 post :create, format: :js,而是切换到明确的 xhr :post, :create, format: :js

3 Railties

请参阅 更改日志 以获取详细的更改。

3.1 移除

  • 删除了 update:application_controller rake 任务。

  • 删除了已弃用的 Rails.application.railties.engines

  • 删除了 Rails Config 中已弃用的 threadsafe!

  • 删除了已弃用的 ActiveRecord::Generators::ActiveModel#update_attributes,改用 ActiveRecord::Generators::ActiveModel#update

  • 删除了已弃用的 config.whiny_nils 选项。

  • 删除了用于运行测试的已弃用的 rake 任务:rake test:uncommittedrake test:recent

3.2 显著更改

  • 现在默认情况下为新的应用程序安装了 Spring 应用程序预加载器。它使用 Gemfile 的 development 组,因此不会安装在生产环境中。(拉取请求)

  • BACKTRACE 环境变量用于显示测试失败的未过滤的回溯。(提交)

  • MiddlewareStack#unshift 公开到环境配置。(拉取请求)

  • 添加了 Application#message_verifier 方法以返回消息验证器。(拉取请求)

  • 默认生成的测试助手所需的 test_help.rb 文件将自动使用 db/schema.rb(或 db/structure.sql)更新你的测试数据库。如果重新加载模式无法解决所有挂起的迁移,它会引发错误。使用 config.active_record.maintain_test_schema = false 退出。(拉取请求)

  • 引入 Rails.gem_version 作为返回 Gem::Version.new(Rails.version) 的便利方法,建议一种更可靠的方法来执行版本比较。(拉取请求)

4 Action Pack

请参阅 更改日志 以获取详细的更改。

4.1 移除

  • 删除了已弃用的 Rails 应用程序回退,用于集成测试,而是设置 ActionDispatch.test_app

  • 删除了已弃用的 page_cache_extension 配置。

  • 删除了已弃用的 ActionController::RecordIdentifier,改用 ActionView::RecordIdentifier

  • 删除了 Action Controller 中已弃用的常量

删除了 继任者
ActionController::AbstractRequest ActionDispatch::Request
ActionController::Request ActionDispatch::Request
ActionController::AbstractResponse ActionDispatch::Response
ActionController::Response ActionDispatch::Response
ActionController::Routing ActionDispatch::Routing
ActionController::Integration ActionDispatch::Integration
ActionController::IntegrationTest ActionDispatch::IntegrationTest

4.2 值得注意的变更

  • protect_from_forgery 也阻止了跨域的 <script> 标签。更新您的测试以使用 xhr :get, :foo, format: :js 代替 get :foo, format: :js。(Pull Request)

  • #url_for 接收一个包含选项的哈希作为数组。(Pull Request)

  • 添加了 session#fetch 方法,其行为类似于 Hash#fetch,不同之处在于返回值始终保存到会话中。(Pull Request)

  • 将 Action View 与 Action Pack 完全分离。(Pull Request)

  • 记录了受深度混淆影响的键。(Pull Request)

  • 新的配置选项 config.action_dispatch.perform_deep_munge 用于选择退出参数“深度混淆”,该混淆用于解决安全漏洞 CVE-2013-0155。(Pull Request)

  • 新的配置选项 config.action_dispatch.cookies_serializer 用于指定签署和加密 Cookie 罐的序列化器。(Pull Requests 1, 2 / 更多详情)

  • 添加了 render :plainrender :htmlrender :body。(Pull Request / 更多详情)

5 Action Mailer

有关详细信息变更,请参阅 变更日志

5.1 值得注意的变更

  • 添加了基于 37 Signals mail_view gem 的邮件预览功能。(Commit)

  • 检测 Action Mailer 消息的生成。生成消息所花费的时间将写入日志。(Pull Request)

6 Active Record

有关详细信息变更,请参阅 变更日志

6.1 移除

  • 删除了对以下 SchemaCache 方法的弃用空传递:primary_keystablescolumnscolumns_hash

  • 删除了 ActiveRecord::Migrator#migrate 中弃用的块过滤器。

  • 删除了 ActiveRecord::Migrator 中弃用的字符串构造函数。

  • 删除了在没有传递可调用对象的情况下使用弃用的 scope

  • 删除了弃用的 transaction_joinable=,支持使用 :joinable 选项的 begin_transaction

  • 删除了弃用的 decrement_open_transactions

  • 删除了弃用的 increment_open_transactions

  • 删除了弃用的 PostgreSQLAdapter#outside_transaction? 方法。您可以使用 #transaction_open? 代替。

  • 删除了弃用的 ActiveRecord::Fixtures.find_table_name,支持 ActiveRecord::Fixtures.default_fixture_model_name

  • 删除了 SchemaStatements 中弃用的 columns_for_remove

  • 删除了弃用的 SchemaStatements#distinct

  • 将弃用的 ActiveRecord::TestCase 移至 Rails 测试套件。该类不再是公共的,仅用于 Rails 内部测试。

  • 删除了对关联中弃用的 :dependent 选项的 :restrict 支持。

  • 删除了对关联中弃用的 :delete_sql:insert_sql:finder_sql:counter_sql 选项的支持。

  • 删除了 Column 中弃用的 type_cast_code 方法。

  • 删除了弃用的 ActiveRecord::Base#connection 方法。确保通过类访问它。

  • 删除了对 auto_explain_threshold_in_seconds 的弃用警告。

  • 删除了 Relation#count 中弃用的 :distinct 选项。

  • 删除了弃用的 partial_updatespartial_updates?partial_updates= 方法。

  • 删除了弃用的 scoped 方法。

  • 删除了弃用的 default_scopes? 方法。

  • 删除了在 4.0 中弃用的隐式联接引用。

  • 删除了 activerecord-deprecated_finders 作为依赖项。有关更多信息,请参阅 该 gem 的 README

  • 删除了 implicit_readonly 的用法。请使用 readonly 方法明确标记记录为 readonly。(Pull Request)

6.2 弃用

  • 弃用了 quoted_locking_column 方法,该方法在任何地方都没有使用。

  • 弃用了 ConnectionAdapters::SchemaStatements#distinct,因为它不再被内部使用。(Pull Request)

  • 弃用了 rake db:test:* 任务,因为测试数据库现在已自动维护。请参阅 railties 版本说明。(Pull Request)

  • 弃用了未使用的 ActiveRecord::Base.symbolized_base_classActiveRecord::Base.symbolized_sti_name,没有替换。 Commit

6.3 值得注意的变更

  • 默认范围不再被链式条件覆盖。

在此更改之前,当您在模型中定义 default_scope 时,它会被同一字段中的链式条件覆盖。现在它像其他范围一样合并。 更多详情

  • 添加了 ActiveRecord::Base.to_param,用于方便地从模型的属性或方法派生“漂亮”的 URL。(Pull Request)

  • 添加了 ActiveRecord::Base.no_touching,它允许忽略对模型的触碰。(Pull Request)

  • 统一了 MysqlAdapterMysql2Adapter 的布尔类型转换。type_cast 将为 true 返回 1,为 false 返回 0。(Pull Request)

  • .unscope 现在删除了 default_scope 中指定的条件。(Commit)

  • 添加了 ActiveRecord::QueryMethods#rewhere,它将覆盖现有的命名 where 条件。(Commit)

  • 扩展了 ActiveRecord::Base#cache_key 以接受可选的时间戳属性列表,其中最高值将被使用。(Commit)

  • 添加了 ActiveRecord::Base#enum 用于声明枚举属性,这些属性的值映射到数据库中的整数,但可以通过名称查询。(Commit)

  • 在写入时类型转换 JSON 值,以便该值与从数据库中读取一致。(Pull Request)

  • 在写入时类型转换 hstore 值,以便该值与从数据库中读取一致。(Commit)

  • 使 next_migration_number 可用于第三方生成器。(Pull Request)

  • 调用 update_attributes 现在将在它收到 nil 参数时抛出 ArgumentError。更具体地说,如果传递给它的参数没有响应 stringify_keys,它将抛出错误。(Pull Request)

  • CollectionAssociation#first/#last(例如 has_many)使用 LIMITed 查询来获取结果,而不是加载整个集合。(Pull Request)

  • Active Record 模型类上的 inspect 不会启动新的连接。这意味着,当数据库丢失时,调用 inspect 不会再抛出异常。(Pull Request)

  • 删除了 count 的列限制,如果 SQL 无效,让数据库抛出异常。(Pull Request)

  • Rails 现在自动检测反向关联。如果您没有在关联上设置 :inverse_of 选项,那么 Active Record 将基于启发式方法猜测反向关联。(Pull Request)

  • 在 ActiveRecord::Relation 中处理别名属性。当使用符号键时,ActiveRecord 现在将别名属性名转换为数据库中使用的实际列名。(Pull Request)

  • 夹具文件中不再评估 ERB,评估上下文不是主对象。多个夹具使用的助手方法应定义在 ActiveRecord::FixtureSet.context_class 中包含的模块上。(Pull Request)

  • 如果显式指定 RAILS_ENV,则不会创建或删除测试数据库。(Pull Request)

  • Relation 不再具有 #map!#delete_if 等变异方法。通过调用 #to_a 将其转换为 Array,然后再使用这些方法。(Pull Request)

  • find_in_batchesfind_eachResult#eachEnumerable#index_by 现在返回一个可以计算其大小的 Enumerator。(Pull Request)

  • scopeenum 和关联现在在“危险”的名称冲突时引发异常。(Pull Request, Pull Request)

  • secondfifth 方法的行为类似于 first 查找器。(Pull Request)

  • 使 touch 触发 after_commitafter_rollback 回调。(Pull Request)

  • sqlite >= 3.8.0 启用部分索引。(Pull Request)

  • 使 change_column_null 可逆。(Commit)

  • 添加了一个标志,用于在迁移后禁用模式转储。这在生产环境中对新应用程序默认设置为 false。(Pull Request)

7 Active Model

有关详细信息变更,请参阅 变更日志

7.1 弃用

  • 弃用 Validator#setup。现在应该在验证器的构造函数中手动完成。(Commit)

7.2 值得注意的变更

  • 添加了新的 API 方法 reset_changeschanges_appliedActiveModel::Dirty,用于控制更改状态。

  • 能够在定义验证时指定多个上下文。(Pull Request)

  • attribute_changed? 现在接受哈希以检查属性是否从给定值 :from 和/或 :to 更改。(Pull Request)

8 Active Support

有关详细信息变更,请参阅 变更日志

8.1 移除

  • 已移除 `MultiJSON` 依赖。 因此,`ActiveSupport::JSON.decode` 不再接受 `MultiJSON` 的选项哈希。 (拉取请求 / 更多详情)

  • 已移除对用于将自定义对象编码为 JSON 的 `encode_json` 钩子的支持。 此功能已提取到 activesupport-json_encoder gem 中。 (相关拉取请求 / 更多详情)

  • 已移除已弃用的 `ActiveSupport::JSON::Variable`,无替代品。

  • 已移除已弃用的 `String#encoding_aware?` 核心扩展 (core_ext/string/encoding)。

  • 已移除已弃用的 `Module#local_constant_names`,改用 `Module#local_constants`。

  • 已移除已弃用的 `DateTime.local_offset`,改用 `DateTime.civil_from_format`。

  • 已移除已弃用的 `Logger` 核心扩展 (core_ext/logger.rb)。

  • 已移除已弃用的 `Time#time_with_datetime_fallback`、`Time#utc_time` 和 `Time#local_time`,改用 `Time#utc` 和 `Time#local`。

  • 已移除已弃用的 `Hash#diff`,无替代品。

  • 已移除已弃用的 `Date#to_time_in_current_zone`,改用 `Date#in_time_zone`。

  • 已移除已弃用的 `Proc#bind`,无替代品。

  • 已移除已弃用的 `Array#uniq_by` 和 `Array#uniq_by!`,请改用原生 `Array#uniq` 和 `Array#uniq!`。

  • 已移除已弃用的 `ActiveSupport::BasicObject`,请改用 `ActiveSupport::ProxyObject`。

  • 已移除已弃用的 `BufferedLogger`,请改用 `ActiveSupport::Logger`。

  • 已移除已弃用的 `assert_present` 和 `assert_blank` 方法,请改用 `assert object.blank?` 和 `assert object.present?`。

  • 已移除过滤器对象的已弃用 `#filter` 方法,请改用相应方法(例如,对于前置过滤器,请改用 `#before`)。

  • 已从默认的词形变化中移除 'cow' => 'kine' 不规则词形变化。 (提交)

8.2 弃用

8.3 显著变化

  • `ActiveSupport` 的 JSON 编码器已重写,以利用 JSON gem,而不是用纯 Ruby 进行自定义编码。 (拉取请求 / 更多详情)

  • 改进了与 JSON gem 的兼容性。 (拉取请求 / 更多详情)

  • 添加了 `ActiveSupport::Testing::TimeHelpers#travel` 和 `#travel_to`。 这些方法通过对 `Time.now` 和 `Date.today` 进行存根,将当前时间更改为给定时间或持续时间。

  • 添加了 `ActiveSupport::Testing::TimeHelpers#travel_back`。 此方法通过移除 `travel` 和 `travel_to` 添加的存根,将当前时间恢复到原始状态。 (拉取请求)

  • 添加了 `Numeric#in_milliseconds`,例如 `1.hour.in_milliseconds`,因此我们可以将它们提供给 JavaScript 函数,例如 `getTime()`。 (提交)

  • 添加了 `Date#middle_of_day`、`DateTime#middle_of_day` 和 `Time#middle_of_day` 方法。 还添加了 `midday`、`noon`、`at_midday`、`at_noon` 和 `at_middle_of_day` 作为别名。 (拉取请求)

  • 添加了 `Date#all_week/month/quarter/year` 用于生成日期范围。 (拉取请求)

  • 添加了 `Time.zone.yesterday` 和 `Time.zone.tomorrow`。 (拉取请求)

  • 添加了 `String#remove(pattern)` 作为 `String#gsub(pattern,'')` 的简写。 (提交)

  • 添加了 `Hash#compact` 和 `Hash#compact!` 用于从哈希中移除值为 nil 的项。 (拉取请求)

  • `blank?` 和 `present?` 承诺返回单例。 (提交)

  • 将新的 `I18n.enforce_available_locales` 配置默认设置为 `true`,这意味着 `I18n` 将确保传递给它的所有语言环境都必须在 `available_locales` 列表中声明。 (拉取请求)

  • 引入了 `Module#concerning`:一种在类中自然地、低仪式地分离职责的方式。 (提交)

  • 添加了 `Object#presence_in` 用于简化将值添加到允许列表中。 (提交)

9 致谢

查看 Rails 的完整贡献者列表,了解为使 Rails 成为稳定而强大的框架而付出了大量时间和精力的众多人士。 向他们致敬。



返回顶部