edge
更多信息请访问 rubyonrails.org: 更多 Ruby on Rails

Ruby on Rails 4.1 发布说明

Rails 4.1 的亮点:

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

1 升级到 Rails 4.1

如果您正在升级现有应用程序,在进行升级之前,最好先进行充分的测试覆盖。如果您尚未升级到 Rails 4.0,请先升级到 Rails 4.0,并确保您的应用程序在升级到 Rails 4.1 之前仍然按预期运行。在升级 Ruby on Rails指南中提供了一份升级时需要注意的事项清单。

2 主要功能

2.1 Spring 应用程序预加载器

Spring 是一个 Rails 应用程序预加载器。它通过在后台保持应用程序运行,加快了开发速度,这样您就不需要每次运行测试、rake 任务或迁移时都启动它。

新的 Rails 4.1 应用程序将附带“springified” 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 # 渲染 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 来查看电子邮件外观的方法。

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

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

预览可在 http://localhost:3000/rails/mailers/notifier/welcome 中访问,并且列表可在 http://localhost: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 # => 所有已归档的 Conversation 的关系

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

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

2.6 消息验证器

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

方法 Rails.application.message_verifier 返回一个新的消息验证器,该验证器使用从 secret_key_base 和给定的消息验证器名称派生的密钥对消息进行签名: ```ruby 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


### Module#concerning

在类中分离责任的一种自然、低仪式的方式:

```ruby
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.7 从远程 <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 配置中删除了已弃用的 threadsafe!

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

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

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

3.2 显著更改

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

  • 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 配置。

  • 删除了 Action Controller 中的已弃用的常量,使用 ActionView::RecordIdentifier 替代。

已删除项 后继者
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。(拉取请求)

  • #url_for 接受一个包含选项的哈希,放在一个数组中。(拉取请求)

  • 添加了 session#fetch 方法,它的行为类似于 Hash#fetch,但返回的值总是保存到会话中。(拉取请求)

  • 完全将 Action View 与 Action Pack 分离。(拉取请求)

  • 记录受深度修改影响的键。(拉取请求)

  • 新的配置选项 config.action_dispatch.perform_deep_munge,用于退出用于解决安全漏洞 CVE-2013-0155 的参数 "deep munging"。(拉取请求)

  • 新的配置选项 config.action_dispatch.cookies_serializer,用于指定签名和加密 cookie 存储的序列化器。(拉取请求, 2 / 更多详情)

  • 添加了 render :plainrender :htmlrender :body。(拉取请求 / 更多详情)

5 Action Mailer

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

5.1 显著更改

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

  • 对 Action Mailer 消息生成进行仪器化。将生成消息所需的时间写入日志。(拉取请求)

6 Active Record

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

6.1 删除

  • SchemaCache 方法中删除了向 nil 传递的已弃用参数:primary_keystablescolumnscolumns_hash

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

  • ActiveRecord::Migrator 中删除了已弃用的 String 构造函数。

  • 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测试。

  • 移除了关联中已弃用的选项: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作为依赖项移除。请参阅宝石自述文件了解更多信息。

  • 不再使用implicit_readonly。请使用readonly方法显式地将记录标记为readonly。(拉取请求)

6.2 弃用

  • 弃用了未使用的quoted_locking_column方法。

  • 弃用了ConnectionAdapters::SchemaStatements#distinct,因为它不再被内部使用。(拉取请求)

  • 弃用了rake db:test:*任务,因为测试数据库现在会自动维护。请参阅railties发布说明。(拉取请求)

  • 弃用了未使用的ActiveRecord::Base.symbolized_base_classActiveRecord::Base.symbolized_sti_name,没有替代方法。提交

6.3 显著变化

  • 默认作用域不再被链式条件覆盖。

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

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

  • 添加了ActiveRecord::Base.no_touching,允许忽略模型上的触发。(拉取请求)

  • 统一MysqlAdapterMysql2Adapter的布尔类型转换。type_cast将返回true1false0。(拉取请求)

  • .unscope现在会删除default_scope中指定的条件。(提交)

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

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

  • 添加了ActiveRecord::Base#enum,用于声明枚举属性,其中值在数据库中映射为整数,但可以通过名称查询。(提交)

  • 在写入时对JSON值进行类型转换,以使值与从数据库读取的值一致。(拉取请求)

  • 在写入时对hstore值进行类型转换,以使值与从数据库读取的值一致。(提交)

  • 使next_migration_number对第三方生成器可访问。(拉取请求)

  • 调用update_attributes现在会在接收到nil参数时抛出ArgumentError。更具体地说,如果传递给它的参数不响应stringify_keys,则会抛出错误。(拉取请求)

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

  • 在Active Record模型类上调用inspect不会初始化新的连接。这意味着在数据库缺失时调用inspect将不再引发异常。(拉取请求)

  • 删除了count的列限制,如果SQL无效,让数据库引发异常。(拉取请求)

  • Rails现在自动检测逆向关联。如果您没有在关联上设置:inverse_of选项,那么Active Record将根据启发法猜测逆向关联。(拉取请求)

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

  • 不再在fixture文件中的ERB中评估主对象的上下文。多个fixture使用的辅助方法应该在包含在ActiveRecord::FixtureSet.context_class中的模块中定义。(拉取请求)

  • 如果明确指定了RAILS_ENV,则不会创建或删除测试数据库。(拉取请求)

  • Relation不再具有#map!#delete_if等改变器方法。在使用这些方法之前,通过调用#to_a将其转换为Array。(拉取请求)

  • find_in_batchesfind_eachResult#eachEnumerable#index_by现在返回一个可以计算其大小的Enumerator。(拉取请求)

  • scopeenum和关联现在在“危险”的名称冲突时引发异常。(拉取请求拉取请求)

  • secondfifth方法的行为类似于first查找器。(拉取请求)

  • 使touch触发after_commitafter_rollback回调。(拉取请求)

  • sqlite >= 3.8.0启用部分索引。 (拉取请求)

  • 使change_column_null可逆。(提交)

  • 添加了一个标志,在迁移后禁用模式转储。在新应用程序的生产环境中,默认设置为false。 (拉取请求)

7 Active Model

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

7.1 弃用

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

7.2 显著更改

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

  • 在定义验证时能够指定多个上下文。(拉取请求)

  • attribute_changed?现在接受一个哈希来检查属性是否已更改为给定的from和/或to值。(拉取请求)

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_fallbackTime#utc_timeTime#local_time,改用Time#utcTime#local

  • 移除了已弃用的Hash#diff,没有替代方法。

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

  • 移除了已弃用的Proc#bind,没有替代方法。

  • 移除了已弃用的Array#uniq_byArray#uniq_by!,改用原生的Array#uniqArray#uniq!

  • 移除了已弃用的ActiveSupport::BasicObject,改用ActiveSupport::ProxyObject

  • 移除了已弃用的BufferedLogger,改用ActiveSupport::Logger

  • 移除了已弃用的assert_presentassert_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.nowDate.today来将当前时间更改为给定的时间或持续时间。

  • 添加了ActiveSupport::Testing::TimeHelpers#travel_back。此方法通过删除traveltravel_to添加的存根,将当前时间返回到原始状态。(拉取请求)

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

  • 添加了Date#middle_of_dayDateTime#middle_of_dayTime#middle_of_day方法。还添加了middaynoonat_middayat_noonat_middle_of_day作为别名。(拉取请求)

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

  • 添加了Time.zone.yesterdayTime.zone.tomorrow。(拉取请求)

反馈

欢迎您帮助改进本指南的质量。

如果您发现任何拼写错误或事实错误,请贡献您的意见。 要开始,请阅读我们的 文档贡献 部分。

您还可能会发现不完整的内容或过时的内容。 请为主要内容添加任何缺失的文档。请先检查 Edge 指南,以验证问题是否已经修复或尚未修复。 请参阅 Ruby on Rails 指南准则 以了解样式和规范。

如果您发现需要修复但无法自行修复的问题,请 提交问题

最后但同样重要的是,欢迎您在 官方 Ruby on Rails 论坛 上讨论有关 Ruby on Rails 文档的任何问题。