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.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.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 並嘗試運行它以提取敏感數據。 這意味著,除非使用xhr,否則任何命中.js URL的測試都將無法通過CSRF保護。請升級您的測試,明確指定期望的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的開發組,因此不會安裝在生產環境中。(拉取請求)

  • 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::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。(拉取請求)

  • #url_for接受包含選項的哈希在數組中。(拉取請求)

  • 添加了session#fetch方法,該方法的行為類似於Hash#fetch,唯一的區別是返回的值始終保存在會話中。(拉取請求)

  • 將Action View完全從Action Pack中分離。(拉取請求)

  • 記錄哪些鍵受到深度修改的影響。(拉取請求)

  • 新的配置選項config.action_dispatch.perform_deep_munge,用於取消參數的“深度修改”,該修改用於解決安全漏洞CVE-2013-0155。(拉取請求)

  • 新的配置選項 config.action_dispatch.cookies_serializer 用於指定簽名和加密 cookie 存儲的序列化器。 (拉取請求 1, 2 / 更多詳情)

  • 添加了 render :plain, render :htmlrender :body。 (拉取請求 1 / 更多詳情)

5 Action Mailer

詳細更改請參考 Changelog

5.1 重要更改

  • 基於 37 Signals mail_view gem 添加了郵件預覽功能。 (提交)

  • 對 Action Mailer 消息生成進行儀表盤記錄。生成消息所需的時間將被記錄到日誌中。 (拉取請求)

6 Active Record

詳細更改請參考 Changelog

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。 (拉取請求)

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。 (Pull Request)

  • 新增 ActiveRecord::Base.no_touching,允許忽略對模型的觸發。 (Pull Request)

  • 統一 MysqlAdapterMysql2Adapter 的布林型轉換。type_cast 將返回 true1false0。 (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)使用 LIMIT 查詢來獲取結果,而不是加載整個集合。 (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和關聯現在會引發「危險」名稱衝突的錯誤。(拉取請求拉取請求)

  • 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 中進行自訂編碼。 (Pull Request / 更多詳細資訊)

  • 改善與 JSON gem 的相容性。 (Pull Request / 更多詳細資訊)

  • 新增 ActiveSupport::Testing::TimeHelpers#travel#travel_to。這些方法通過存根 Time.nowDate.today,將當前時間更改為指定的時間或持續時間。

  • 新增 ActiveSupport::Testing::TimeHelpers#travel_back。此方法通過刪除 traveltravel_to 添加的存根,將當前時間返回到原始狀態。(Pull Request)

  • 新增 Numeric#in_milliseconds,例如 1.hour.in_milliseconds,以便將它們傳遞給 JavaScript 函數,如 getTime()。(Commit)

  • 新增 Date#middle_of_dayDateTime#middle_of_dayTime#middle_of_day 方法。還新增了 middaynoonat_middayat_noonat_middle_of_day 作為別名。(Pull Request)

  • 新增 Date#all_week/month/quarter/year 用於生成日期範圍。(Pull Request)

  • 新增 Time.zone.yesterdayTime.zone.tomorrow。(Pull Request)

  • 新增 String#remove(pattern) 作為常見模式 String#gsub(pattern,'') 的簡寫。(Commit)

  • 新增 Hash#compactHash#compact! 用於從哈希中刪除值為 nil 的項目。(Pull Request)

  • blank?present? 現在返回單例值。(Commit)

  • 將新的 I18n.enforce_available_locales 配置默認為 true,這意味著 I18n 將確保所有傳遞給它的區域必須在 available_locales 列表中聲明。(Pull Request)

  • 引入 Module#concerning:一種自然、低儀式的方式來在類中分離責任。(Commit)

  • 新增 Object#presence_in,以簡化將值添加到允許列表的操作。(Commit)

9 貢獻者

請參閱 Rails 的完整貢獻者列表,感謝那些花了很多時間使 Rails 成為穩定且強大的框架的人。向他們致敬。

回饋

歡迎協助提升本指南的品質。

如果您發現任何錯別字或事實錯誤,請貢獻您的力量。 開始之前,您可以閱讀我們的 文件貢獻 部分。

您也可能會發現不完整的內容或過時的資訊。 請為主要的文件補充任何遺漏的內容。請先檢查 Edge 指南,以確認問題是否已經修復或尚未在主分支上修復。 請參考 Ruby on Rails 指南指引 以了解風格和慣例。

如果您發現需要修復但無法自行修補的問題,請 開啟一個問題

最後但同樣重要的是,關於 Ruby on Rails 文件的任何討論都非常歡迎在 官方 Ruby on Rails 論壇 上進行。