更多内容请访问 rubyonrails.org:

Ruby on Rails 3.1 发布说明

Rails 3.1 的亮点

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

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

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. 嵌入 Gem

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

更多信息: - bundler 主页

2.2. 前沿开发

BundlerGemfile 使冻结您的 Rails 应用程序变得轻而易举,使用新的专用 bundle 命令。如果您想直接从 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 gem 提供。

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

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

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

  • Scaffold 和 app 生成器在 Ruby 1.9 上运行时使用 Ruby 1.9 风格的哈希。要生成旧风格的哈希,可以传递 --old-style-hash

  • Scaffold 控制器生成器为 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。默认情况下,ActionController::Base 中会执行 helper :all,它默认包含所有助手。将 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 处的文档。

  • redirect 路由方法现在还接受一个选项哈希,该哈希将仅更改 URL 中的相关部分,或者接受一个响应 call 的对象,从而允许重定向被重用。

5.2. Action Dispatch

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

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

  • 添加了 ActionDispatch::Request.ignore_accept_header 以忽略 accept 头。

  • 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 仅要求模板处理程序响应 call。

  • 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() 的别名。这取代了 JSON gem 在使用 JavaScriptHelper 的模板中添加的 Object#j() 方法。

  • 允许 datetime 选择器中使用 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 或任何其他响应 call 的对象,用于惰性求值。

  • 默认作用域现在在可能的最晚时间进行评估,以避免作用域隐式包含默认作用域的问题,然后通过 Model.unscoped 无法摆脱默认作用域。

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

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

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

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

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

  • 除非同时提供 limits 和 offsets,否则将从 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 选项。出于历史和实际原因,association.delete(*records) 默认采用 :delete_all 删除策略,尽管常规 has_many 的默认策略是 :nullify。此外,这仅在源反射是 belongs_to 时才有效。对于其他情况,您应该直接修改 through 关联。

  • has_and_belongs_to_manyhas_many :throughassociation.destroy 行为已更改。从现在开始,关联上的“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,id 字段为 nil,并且可以保存。

  • 查询缓存现在与预处理语句一起使用。应用程序中无需进行任何更改。

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 整理



回到顶部