更多内容请访问 rubyonrails.org:

Ruby on Rails 3.1 版本发布说明

Rails 3.1 中的亮点

  • 流式传输
  • 可逆迁移
  • 资产管道
  • jQuery 作为默认 JavaScript 库

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

1 升级到 Rails 3.1

如果您要升级现有应用程序,最好在升级之前拥有良好的测试覆盖率。您还应该先升级到 Rails 3(如果您尚未升级),并确保您的应用程序在尝试升级到 Rails 3.1 之前能够正常运行。然后注意以下更改

1.1 Rails 3.1 要求至少使用 Ruby 1.8.7

Rails 3.1 要求使用 Ruby 1.8.7 或更高版本。对所有先前 Ruby 版本的支持已正式取消,您应尽快升级。Rails 3.1 也与 Ruby 1.9.2 兼容。

请注意,Ruby 1.8.7 p248 和 p249 存在序列化错误,会导致 Rails 崩溃。但是,Ruby Enterprise Edition 自 1.8.7-2010.02 版本开始修复了这些错误。在 1.9 方面,Ruby 1.9.1 无法使用,因为它会导致直接段错误,因此如果您想使用 1.9.x,请直接跳到 1.9.2 以确保顺利运行。

1.2 在您的应用程序中需要更新的内容

以下更改用于将您的应用程序升级到 Rails 3.1.3,这是 Rails 的最新 3.1.x 版本。

1.2.1 Gemfile

对您的 Gemfile 进行以下更改。

gem "rails", "= 3.1.3"
gem "mysql2"

# Needed for the new asset pipeline
group :assets do
  gem "sass-rails",   "~> 3.1.5"
  gem "coffee-rails", "~> 3.1.1"
  gem "uglifier",     ">= 1.0.3"
end

# jQuery is the default JavaScript library in Rails 3.1
gem "jquery-rails"

1.2.2 config/application.rb

  • 资产管道需要以下添加

    config.assets.enabled = true
    config.assets.version = '1.0'
    
  • 如果您的应用程序使用“/assets”路由访问资源,您可能想要更改用于资产的预设以避免冲突

    # Defaults to '/assets'
    config.assets.prefix = '/asset-files'
    

1.2.3 config/environments/development.rb

  • 删除 RJS 设置 config.action_view.debug_rjs = true

  • 如果您启用了资产管道,请添加以下内容。

    # Do not compress assets
    config.assets.compress = false
    
    # Expands the lines which load the assets
    config.assets.debug = true
    

1.2.4 config/environments/production.rb

  • 同样,以下大部分更改都是为了资产管道。您可以在 资产管道 指南中详细了解这些内容。

    # Compress JavaScripts and CSS
    config.assets.compress = true
    
    # Don't fallback to assets pipeline if a precompiled asset is missed
    config.assets.compile = false
    
    # Generate digests for assets URLs
    config.assets.digest = true
    
    # Defaults to Rails.root.join("public/assets")
    # config.assets.manifest = YOUR_PATH
    
    # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
    # config.assets.precompile `= %w( admin.js admin.css )
    
    # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
    # config.force_ssl = true
    

1.2.5 config/environments/test.rb

# Configure static asset server for tests with Cache-Control for performance
config.serve_static_assets = true
config.static_cache_control = "public, max-age=3600"

1.2.6 config/initializers/wrap_parameters.rb

  • 如果您希望将参数包装到嵌套的哈希中,请添加此文件并包含以下内容。在新应用程序中默认启用此功能。

    # Be sure to restart your server when you modify this file.
    # This file contains settings for ActionController::ParamsWrapper which
    # is enabled by default.
    
    # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
    ActiveSupport.on_load(:action_controller) do
      wrap_parameters :format => [:json]
    end
    
    # Disable root element in JSON by default.
    ActiveSupport.on_load(:active_record) do
      self.include_root_in_json = false
    end
    

1.2.7 删除视图中资产辅助方法引用中的 :cache 和 :concat 选项

  • 使用资产管道后,:cache 和 :concat 选项不再使用,请从您的视图中删除这些选项。

2 创建 Rails 3.1 应用程序

# You should have the 'rails' RubyGem installed
$ rails new myapp
$ cd myapp

2.1 供应商化 Gems

Rails 现在在应用程序根目录中使用 Gemfile 来确定应用程序启动所需的 gems。GemfileBundler gem 处理,然后安装所有依赖项。它甚至可以将所有依赖项本地安装到您的应用程序中,这样它就不依赖于系统 gems。

更多信息:- bundler 主页

2.2 使用最新版本

BundlerGemfile 使得使用新的专用 bundle 命令轻松地冻结 Rails 应用程序。如果您想直接从 Git 存储库进行捆绑,可以传递 --edge 标志

$ rails new myapp --edge

如果您有 Rails 存储库的本地检出,并且想要使用它来生成应用程序,可以传递 --dev 标志

$ ruby /path/to/rails/railties/bin/rails new myapp --dev

3 Rails 架构更改

3.1 资产管道

Rails 3.1 中的主要变化是资产管道。它使 CSS 和 JavaScript 成为一等公民,并支持适当的组织,包括在插件和引擎中的使用。

资产管道由 Sprockets 提供支持,并在 资产管道 指南中进行了介绍。

3.2 HTTP 流式传输

HTTP 流式传输是 Rails 3.1 中的另一个新变化。它允许浏览器在服务器仍在生成响应时下载您的样式表和 JavaScript 文件。这需要 Ruby 1.9.2,是可选功能,也需要 Web 服务器的支持,但 NGINX 和 Unicorn 的流行组合已准备好利用它。

3.3 默认 JS 库现在是 jQuery

jQuery 是 Rails 3.1 附带的默认 JavaScript 库。但如果您使用 Prototype,切换起来很简单。

$ rails new myapp -j prototype

3.4 标识映射

Active Record 在 Rails 3.1 中包含标识映射。标识映射保存先前实例化的记录,如果再次访问,则返回与记录关联的对象。标识映射在每次请求的基础上创建,并在请求完成时刷新。

Rails 3.1 默认情况下关闭了标识映射。

4 Railties

  • jQuery 是新的默认 JavaScript 库。

  • jQuery 和 Prototype 不再捆绑,现在由 jquery-railsprototype-rails gems 提供。

  • 应用程序生成器接受一个选项 -j,它可以是任意字符串。如果传递“foo”,则 gem“foo-rails”将添加到 Gemfile 中,并且应用程序 JavaScript 清单文件将要求“foo”和“foo_ujs”。目前,只有“prototype-rails”和“jquery-rails”存在并通过资产管道提供这些文件。

  • 生成应用程序或插件会运行 bundle install,除非指定了 --skip-gemfile--skip-bundle

  • 控制器和资源生成器现在会自动生成资产存根(可以通过 --skip-assets 关闭)。这些存根将使用 CoffeeScript 和 Sass,如果这些库可用。

  • 脚手架和应用程序生成器在 Ruby 1.9 上运行时使用 Ruby 1.9 风格的哈希。要生成旧风格的哈希,可以传递 --old-style-hash

  • 脚手架控制器生成器为 JSON 创建格式块,而不是 XML。

  • Active Record 日志记录被定向到 STDOUT 并在控制台中内联显示。

  • 添加了 config.force_ssl 配置,它会加载 Rack::SSL 中间件并强制所有请求都使用 HTTPS 协议。

  • 添加了 rails plugin new 命令,它会生成一个包含 gemspec、测试和用于测试的模拟应用程序的 Rails 插件。

  • 在默认中间件栈中添加了Rack::EtagRack::ConditionalGet

  • 在默认中间件栈中添加了Rack::Cache

  • 引擎进行了重大更新 - 你可以在任何路径上挂载它们,启用资产,运行生成器,等等。

5 Action Pack

5.1 Action Controller

  • 如果无法验证 CSRF 令牌的真实性,则会发出警告。

  • 在控制器中指定force_ssl以强制浏览器通过 HTTPS 协议在该特定控制器上传输数据。要限制为特定操作,可以使用:only:except

  • config.filter_parameters中指定的敏感查询字符串参数现在将从日志中的请求路径中过滤掉。

  • 对于to_param返回nil的 URL 参数现在将从查询字符串中删除。

  • 添加了ActionController::ParamsWrapper 来将参数包装到嵌套哈希中,并且默认情况下将在新应用程序中为 JSON 请求启用。这可以在config/initializers/wrap_parameters.rb中自定义。

  • 添加了config.action_controller.include_all_helpers。默认情况下,helper :all是在ActionController::Base中完成的,这默认情况下包含所有助手。将include_all_helpers设置为false将导致只包含application_helper和与控制器相对应的助手(如 foo_controller 的 foo_helper)。

  • url_for和命名 URL 助手现在接受:subdomain:domain作为选项。

  • 添加了Base.http_basic_authenticate_with来通过单个类方法调用执行简单的 http 基本身份验证。

    class PostsController < ApplicationController
      USER_NAME, PASSWORD = "dhh", "secret"
    
      before_filter :authenticate, :except => [ :index ]
    
      def index
        render :text => "Everyone can see me!"
      end
    
      def edit
        render :text => "I'm only accessible if you know the password"
      end
    
      private
        def authenticate
          authenticate_or_request_with_http_basic do |user_name, password|
            user_name == USER_NAME && password == PASSWORD
          end
        end
    end
    

    现在可以写成

    class PostsController < ApplicationController
      http_basic_authenticate_with :name => "dhh", :password => "secret", :except => :index
    
      def index
        render :text => "Everyone can see me!"
      end
    
      def edit
        render :text => "I'm only accessible if you know the password"
      end
    end
    
  • 添加了流支持,你可以使用以下命令启用它

    class PostsController < ActionController::Base
      stream
    end
    

    你可以使用:only:except将其限制为某些操作。有关更多信息,请阅读ActionController::Streaming中的文档。

  • 重定向路由方法现在也接受一个选项哈希,它只会更改 URL 中相关的部分,或者一个响应调用的对象,允许重定向被重复使用。

5.2 Action Dispatch

  • config.action_dispatch.x_sendfile_header现在默认为nilconfig/environments/production.rb没有为其设置任何特定值。这允许服务器通过X-Sendfile-Type来设置它。

  • ActionDispatch::MiddlewareStack现在使用组合而不是继承,不再是一个数组。

  • 添加了ActionDispatch::Request.ignore_accept_header来忽略接受标头。

  • 在默认堆栈中添加了Rack::Cache

  • 将 etag 的责任从ActionDispatch::Response移动到中间件栈。

  • 依赖于Rack::Session存储的 API,以提高在 Ruby 世界中的兼容性。这与以前不兼容,因为Rack::Session期望#get_session接受四个参数,并且需要#destroy_session而不是简单的#destroy

  • 模板查找现在会在继承链中向上搜索。

5.3 Action View

  • form_tag添加了一个:authenticity_token选项,用于自定义处理或通过传递:authenticity_token => false来省略令牌。

  • 创建了ActionView::Renderer并指定了ActionView::Context的 API。

  • 在 Rails 3.1 中禁止在原位对SafeBuffer进行修改。

  • 添加了 HTML5 button_tag 助手。

  • file_field会自动将:multipart => true添加到包含的表单中。

  • 添加了一个便捷的惯用法,以便从:data选项哈希中在标签助手中生成 HTML5 data-* 属性

    tag("div", :data => {:name => 'Stephen', :city_state => %w(Chicago IL)})
    # => <div data-name="Stephen" data-city-state="[&quot;Chicago&quot;,&quot;IL&quot;]" />
    

键被破折号化。值被 JSON 编码,除了字符串和符号。

  • csrf_meta_tag被重命名为csrf_meta_tags,并为向后兼容性创建了别名csrf_meta_tag

  • 旧的模板处理程序 API 已被弃用,新的 API 只需要模板处理程序响应调用。

  • rhtml 和 rxml 终于作为模板处理程序被移除。

  • config.action_view.cache_template_loading被带回来,它允许你决定是否应该缓存模板。

  • 提交表单助手不再生成 id "object_name_id"。

  • 允许FormHelper#form_for直接指定:method作为选项,而不是通过:html哈希。form_for(@post, remote: true, method: :delete)而不是form_for(@post, remote: true, html: { method: :delete })

  • 提供JavaScriptHelper#j()作为JavaScriptHelper#escape_javascript()的别名。这取代了Object#j()方法,该方法是 JSON gem 在使用 JavaScriptHelper 的模板中添加的。

  • 允许在日期时间选择器中使用 AM/PM 格式。

  • auto_link已从 Rails 中移除,并提取到rails_autolink gem中。

6 Active Record

  • 添加了一个类方法pluralize_table_names来对单个模型的表名进行单复数化。以前,这只能通过ActiveRecord::Base.pluralize_table_names全局设置所有模型。

    class User < ActiveRecord::Base
      self.pluralize_table_names = false
    end
    
  • 添加了对单数关联的属性的块设置。该块将在实例初始化后被调用。

    class User < ActiveRecord::Base
      has_one :account
    end
    
    user.build_account{ |a| a.credit_limit = 100.0 }
    
  • 添加了ActiveRecord::Base.attribute_names来返回属性名称列表。如果模型是抽象的或表不存在,这将返回一个空数组。

  • CSV Fixtures 已被弃用,将在 Rails 3.2.0 中删除支持。

  • ActiveRecord#newActiveRecord#createActiveRecord#update_attributes都接受第二个哈希作为选项,允许你指定在分配属性时要考虑的角色。这是建立在 Active Model 的新批量赋值功能之上的。

    class Post < ActiveRecord::Base
      attr_accessible :title
      attr_accessible :title, :published_at, :as => :admin
    end
    
    Post.new(params[:post], :as => :admin)
    
  • default_scope现在可以接受一个块、lambda 或任何其他响应调用的对象,用于延迟评估。

  • 默认作用域现在将在尽可能晚的时候进行评估,以避免作用域的创建会隐含地包含默认作用域,然后就无法通过 Model.unscoped 来摆脱它。

  • PostgreSQL 适配器只支持 PostgreSQL 8.2 及更高版本。

  • ConnectionManagement 中间件已更改为在 rack 主体刷新后清理连接池。

  • 在 Active Record 上添加了一个update_column方法。此新方法更新对象上的给定属性,跳过验证和回调。建议使用update_attributesupdate_attribute,除非你确定不想执行任何回调,包括修改updated_at列。它不应在新的记录上调用。

  • 具有:through选项的关联现在可以使用任何关联作为通过或源关联,包括其他具有:through选项的关联和has_and_belongs_to_many关联。

  • 当前数据库连接的配置现在可以通过ActiveRecord::Base.connection_config访问。

  • 从 COUNT 查询中删除了限制和偏移量,除非两者都提供。

    People.limit(1).count           # => 'SELECT COUNT(*) FROM people'
    People.offset(1).count          # => 'SELECT COUNT(*) FROM people'
    People.limit(1).offset(1).count # => 'SELECT COUNT(*) FROM people LIMIT 1 OFFSET 1'
    
  • ActiveRecord::Associations::AssociationProxy已被拆分。现在有一个Association类(及其子类),它们负责对关联进行操作,然后是一个单独的、薄薄的包装器称为CollectionProxy,它代理集合关联。这可以防止命名空间污染,分离关注点,并允许进一步的重构。

  • 单数关联 (has_onebelongs_to) 不再具有代理,只返回关联的记录或nil。这意味着你不应该使用未公开的方法,如bob.mother.create - 而是使用bob.create_mother

  • 支持has_many :through关联上的:dependent选项。出于历史和实际原因,尽管默认策略是:nullify用于常规 has_many,但:delete_allassociation.delete(*records)采用的默认删除策略。另外,这只有在源反射是 belongs_to 的情况下才有效。对于其他情况,你应该直接修改通过关联。

  • association.destroy的行为对于has_and_belongs_to_manyhas_many :through进行了更改。从现在开始,关联上的“destroy”或“delete”将被理解为“摆脱链接”,而不是(一定)“摆脱关联的记录”。

  • 以前,has_and_belongs_to_many.destroy(*records)会销毁记录本身。它不会删除连接表中的任何记录。现在,它删除连接表中的记录。

  • 以前,has_many_through.destroy(*records)会销毁记录本身,以及连接表中的记录。[注意:情况并非总是如此;以前版本的 Rails 只会销毁记录本身。]现在,它只销毁连接表中的记录。

  • 请注意,这种变化在一定程度上与以前不兼容,但不幸的是,在更改之前没有办法“弃用”它。进行此更改是为了使“destroy”或“delete”的含义在不同类型的关联中保持一致。如果你希望销毁记录本身,你可以执行records.association.each(&:destroy)

  • change_table添加:bulk => true选项,以便使用单个 ALTER 语句来进行块中定义的所有模式更改。

    change_table(:users, :bulk => true) do |t|
      t.string :company_name
      t.change :birthdate, :datetime
    end
    
  • 删除了对访问has_and_belongs_to_many连接表上的属性的支持。需要使用has_many :through

  • has_onebelongs_to关联添加了一个create_association!方法。

  • 迁移现在是可逆的,这意味着 Rails 将找出如何反转你的迁移。要使用可逆迁移,只需定义change方法即可。

    class MyMigration < ActiveRecord::Migration
      def change
        create_table(:horses) do |t|
          t.column :content, :text
          t.column :remind_at, :datetime
        end
      end
    end
    
  • 有些事情无法自动为你反转。如果你知道如何反转这些事情,你应该在你的迁移中定义updown。如果你在 change 中定义了无法反转的内容,则在向下执行时将引发IrreversibleMigration异常。

  • 迁移现在使用实例方法而不是类方法

    class FooMigration < ActiveRecord::Migration
      def up # Not self.up
        # ...
      end
    end
    
  • 从模型和结构迁移生成器生成的迁移文件(例如,add_name_to_users)使用可逆迁移的change方法,而不是普通的updown方法。

  • 删除了对关联上的字符串 SQL 条件进行插值的支持。相反,应该使用 proc。

    has_many :things, :conditions => 'foo = #{bar}'          # before
    has_many :things, :conditions => proc { "foo = #{bar}" } # after
    

    在 proc 内部,self是关联的所有者,除非你正在热加载关联,在这种情况下,self是关联所在的类。

    你可以在 proc 内部添加任何“正常”条件,因此以下内容也将有效

    has_many :things, :conditions => proc { ["foo = ?", bar] }
    
  • 以前,has_and_belongs_to_many关联上的:insert_sql:delete_sql允许你调用“record”来获取要插入或删除的记录。现在,它作为参数传递给 proc。

  • 添加了ActiveRecord::Base#has_secure_password(通过ActiveModel::SecurePassword)来封装使用 BCrypt 加密和加盐的简单密码使用。

    # Schema: User(name:string, password_digest:string, password_salt:string)
    class User < ActiveRecord::Base
      has_secure_password
    end
    
  • 当生成模型时,默认情况下会为belongs_toreferences列添加add_index

  • 设置belongs_to对象的 id 将更新对该对象的引用。

  • ActiveRecord::Base#dupActiveRecord::Base#clone 的语义已更改,以更接近普通的 Ruby dup 和 clone 语义。

  • 调用 ActiveRecord::Base#clone 将导致对记录进行浅层复制,包括复制冻结状态。不会调用任何回调。

  • 调用 ActiveRecord::Base#dup 将复制记录,包括调用初始化后的钩子。不会复制冻结状态,并且所有关联都将被清除。复制的记录将对 new_record? 返回 true,具有 nil 的 id 字段,并且可以保存。

  • 查询缓存现在可以使用准备好的语句。应用程序不需要进行任何更改。

7 Active Model

  • attr_accessible 接受一个选项 :as 以指定角色。

  • InclusionValidatorExclusionValidatorFormatValidator 现在接受一个选项,该选项可以是 proc、lambda 或任何响应 call 的对象。此选项将使用当前记录作为参数调用,并返回一个响应 include? 的对象(用于 InclusionValidatorExclusionValidator),并为 FormatValidator 返回一个正则表达式对象。

  • 添加了 ActiveModel::SecurePassword 来封装使用 BCrypt 加密和加盐的简单密码使用。

  • ActiveModel::AttributeMethods 允许按需定义属性。

  • 添加了对选择性启用和禁用观察者的支持。

  • 不再支持备用 I18n 命名空间查找。

8 Active Resource

  • 所有请求的默认格式已更改为 JSON。如果您想继续使用 XML,则需要在类中设置 self.format = :xml。例如,

    class User < ActiveResource::Base
      self.format = :xml
    end
    

9 Active Support

  • ActiveSupport::Dependencies 现在在 load_missing_constant 中找到现有常量时会引发 NameError

  • 添加了一个新的报告方法 Kernel#quietly,它可以静默 STDOUTSTDERR

  • 添加了 String#inquiry 作为将字符串转换为 StringInquirer 对象的便捷方法。

  • 添加了 Object#in? 来测试一个对象是否包含在另一个对象中。

  • LocalCache 策略现在是一个真正的中间件类,不再是一个匿名类。

  • ActiveSupport::Dependencies::ClassCache 类已引入,用于保存对可重新加载类的引用。

  • ActiveSupport::Dependencies::Reference 已重构,以直接利用新的 ClassCache

  • 在 Ruby 1.8 中,Range#cover? 作为 Range#include? 的别名。

  • 在 Date/DateTime/Time 中添加了 weeks_agoprev_week

  • ActiveSupport::Dependencies.remove_unloadable_constants! 中添加了 before_remove_const 回调。

弃用

  • ActiveSupport::SecureRandom 已被 Ruby 标准库中的 SecureRandom 弃用。

10 鸣谢

查看 Rails 贡献者完整列表,了解为 Rails 投入大量时间并使其成为稳定、强大的框架的许多人。向他们所有人致敬。

Rails 3.1 版本说明由 Vijay Dev 编译



返回顶部