v7.1.3.2
更多資訊請至 rubyonrails.org: 更多 Ruby on Rails

Ruby on Rails 2.3 版本說明

Rails 2.3 提供了各種新功能和改良功能,包括全面的 Rack 整合、更新的 Rails Engines 支援、Active Record 的巢狀交易、動態和預設範圍、統一的呈現、更有效率的路由、應用程式範本和安靜的回溯。此清單涵蓋了主要的升級,但不包括所有小錯誤修正和變更。如果您想查看所有內容,請查看 GitHub 上 Rails 主要儲存庫中的提交清單,或檢閱各個 Rails 元件的 CHANGELOG 檔案。

1 應用程式架構

Rails 應用程式的架構中有兩項重大變更:完全整合 Rack 模組化網路伺服器介面,以及重新支援 Rails Engines。

1.1 Rack 整合

Rails 已與其 CGI 過往決裂,並在各處使用 Rack。這需要且導致大量的內部變更(但如果您使用 CGI,不用擔心;Rails 現在透過代理介面支援 CGI)。儘管如此,這對 Rails 內部來說仍是一項重大變更。升級至 2.3 後,您應在您的本機環境和生產環境中進行測試。一些測試事項

  • 階段
  • Cookie
  • 檔案上傳
  • JSON/XML API

以下是與 rack 相關變更的摘要

  • script/server 已切換為使用 Rack,表示它支援任何與 Rack 相容的伺服器。如果存在,script/server 也會選取 rackup 設定檔。預設情況下,它會尋找 config.ru 檔案,但您可以使用 -c 切換來覆寫此設定。
  • FCGI 處理程式會透過 Rack 執行。
  • ActionController::Dispatcher 保留其自己的預設中間件堆疊。可以注入、重新排序和移除中間件。堆疊會在開機時編譯成一個鏈。您可以在 environment.rb 中設定中間件堆疊。
  • 已新增 rake middleware 任務來檢查中間件堆疊。這對於除錯中間件堆疊順序很有用。
  • 已修改整合測試執行器,以執行整個中間件和應用程式堆疊。這使得整合測試非常適合測試 Rack 中間件。
  • ActionController::CGIHandler 是 Rack 的向下相容 CGI 封裝器。CGIHandler 的目的是取得舊的 CGI 物件,並將其環境資訊轉換成與 Rack 相容的形式。
  • 已移除 CgiRequestCgiResponse
  • 現在會延遲載入階段儲存。如果您在要求期間從未存取階段物件,它將永遠不會嘗試載入階段資料(剖析 cookie、從 memcache 載入資料或查詢 Active Record 物件)。
  • 您不再需要在測試中使用 CGI::Cookie.new 來設定 cookie 值。將 String 值指定給 request.cookies["foo"] 現在會如預期般設定 cookie。
  • CGI::Session::CookieStore 已由 ActionController::Session::CookieStore 取代。
  • CGI::Session::MemCacheStore 已由 ActionController::Session::MemCacheStore 取代。
  • CGI::Session::ActiveRecordStore 已由 ActiveRecord::SessionStore 取代。
  • 您仍可以使用 ActionController::Base.session_store = :active_record_store 來變更階段儲存。
  • 預設階段選項仍使用 ActionController::Base.session = { :key => "..." } 設定。不過,:session_domain 選項已重新命名為 :domain
  • 通常會包覆整個要求的互斥鎖已移至中間件 ActionController::Lock 中。
  • ActionController::AbstractRequestActionController::Request 已統一。新的 ActionController::Request 繼承自 Rack::Request。這會影響測試要求中對 response.headers['type'] 的存取。請改用 response.content_type
  • 如果已載入 ActiveRecordActiveRecord::QueryCache 中介軟體會自動插入中介軟體堆疊。此中介軟體會設定並清除每個要求的 Active Record 查詢快取。
  • Rails 路由器和控制器類別遵循 Rack 規格。你可以使用 SomeController.call(env) 直接呼叫控制器。路由器會將路由參數儲存在 rack.routing_args 中。
  • ActionController::Request 繼承自 Rack::Request
  • 請改用 config.action_controller.session = { :key => 'foo', ...,而非 config.action_controller.session = { :session_key => 'foo', ...
  • 使用 ParamsParser 中介軟體會預先處理任何 XML、JSON 或 YAML 要求,以便在之後使用任何 Rack::Request 物件正常讀取這些要求。

1.2 重新支援 Rails 引擎

在經過一些沒有升級的版本後,Rails 2.3 為 Rails 引擎(可以在其他應用程式中嵌入的 Rails 應用程式)提供了部分新功能。首先,引擎中的路由檔案現在會自動載入和重新載入,就像你的 routes.rb 檔案一樣(這也適用於其他外掛程式中的路由檔案)。其次,如果你的外掛程式有 app 資料夾,則 app/[models|controllers|helpers] 會自動新增至 Rails 載入路徑。引擎現在也支援新增檢視路徑,而且 Action Mailer 和 Action View 會使用引擎和其他外掛程式的檢視。

2 文件

Ruby on Rails 指南專案已為 Rails 2.3 發布了多個額外指南。此外,一個獨立網站維護著 Edge Rails 指南的更新副本。其他文件工作包括Rails wiki的重新啟動,以及 Rails Book 的早期規劃。

3 Ruby 1.9.1 支援

Rails 2.3 應該會通過所有自己的測試,無論您是在 Ruby 1.8 或現在已發布的 Ruby 1.9.1 上執行。不過,您應該知道,移轉到 1.9.1 需要檢查所有資料轉接器、外掛程式,以及您依賴於 Ruby 1.9.1 相容性的其他程式碼,以及 Rails 核心。

4 Active Record

Active Record 在 Rails 2.3 中獲得相當多的新功能和錯誤修正。重點包括巢狀屬性、巢狀交易、動態和預設範圍,以及批次處理。

4.1 巢狀屬性

Active Record 現在可以直接更新巢狀模型的屬性,只要您告訴它這樣做

class Book < ActiveRecord::Base
  has_one :author
  has_many :pages

  accepts_nested_attributes_for :author, :pages
end

開啟巢狀屬性會啟用許多事情:自動(和原子)儲存記錄及其關聯的子項、子項感知驗證,以及支援巢狀表單(稍後討論)。

您也可以使用 :reject_if 選項,指定透過巢狀屬性新增的任何新記錄的要求

accepts_nested_attributes_for :author,
  :reject_if => proc { |attributes| attributes['name'].blank? }

4.2 巢狀交易

Active Record 現在支援巢狀交易,這是一個非常需要的功能。現在您可以撰寫像這樣的程式碼

User.transaction do
  User.create(:username => 'Admin')
  User.transaction(:requires_new => true) do
    User.create(:username => 'Regular')
    raise ActiveRecord::Rollback
  end
end

User.find(:all)  # => Returns only Admin

巢狀交易讓您可以回滾內部交易,而不會影響外部交易的狀態。如果您希望交易是巢狀的,您必須明確新增 :requires_new 選項;否則,巢狀交易只會成為父交易的一部分(就像目前在 Rails 2.2 上一樣)。在底層,巢狀交易是 使用儲存點,因此即使在沒有真正巢狀交易的資料庫上,也支援它們。還有一些神奇的事情發生,讓這些交易在測試期間與交易固定裝置配合良好。

4.3 動態範圍

您知道 Rails 中的動態尋找器(允許您臨時編造像 find_by_color_and_flavor 這樣的函式)和已命名範圍(允許您將可重複使用的查詢條件封裝成友善的名稱,例如 currently_active)。現在,您可以擁有動態範圍函式。這個想法是組合語法,允許動態過濾函式鏈結。例如

Order.scoped_by_customer_id(12)
Order.scoped_by_customer_id(12).find(:all,
  :conditions => "status = 'open'")
Order.scoped_by_customer_id(12).scoped_by_status("open")

使用動態範圍不需要定義任何內容:它們只會運作。

4.4 預設範圍

Rails 2.3 將引入預設範圍的概念,類似於已命名範圍,但套用於模型中的所有已命名範圍或尋找函式。例如,您可以撰寫 default_scope :order => 'name ASC',而任何時候您從該模型中擷取記錄時,它們都會按名稱排序(除非您覆寫選項)。

4.5 批次處理

現在,您可以使用 find_in_batches 透過較少的記憶體壓力處理來自 Active Record 模型的大量記錄

Customer.find_in_batches(:conditions => {:active => true}) do |customer_group|
  customer_group.each { |customer| customer.update_account_balance! }
end

您可以將大部分 find 選項傳遞到 find_in_batches。但是,您無法指定記錄的傳回順序(它們將始終按主鍵遞增順序傳回,主鍵必須是整數),或使用 :limit 選項。相反,使用 :batch_size 選項(預設為 1000)來設定每個批次中傳回的記錄數。

新的 find_each 方法提供一個 find_in_batches 的包裝器,可傳回個別記錄,而尋找本身則以批次(預設為 1000)進行

Customer.find_each do |customer|
  customer.update_account_balance!
end

請注意,您只應將此方法用於批次處理:對於少量記錄(少於 1000),您應只使用一般尋找方法搭配自己的迴圈。

4.6 回呼的多重條件

在使用 Active Record 回呼時,您現在可以在同一個回呼中結合 :if:unless 選項,並提供多重條件作為陣列

before_save :update_credit_rating, :if => :active,
  :unless => [:admin, :cash_only]
  • 主要貢獻者:L. Caviola

4.7 使用 having 尋找

Rails 現在在尋找時有一個 :having 選項(以及在 has_manyhas_and_belongs_to_many 關聯中),用於在群組尋找中過濾記錄。正如那些有豐富 SQL 背景的人所知,這允許根據群組結果進行過濾

developers = Developer.find(:all, :group => "salary",
  :having => "sum(salary) > 10000", :select => "salary")

4.8 重新連接 MySQL 連線

MySQL 在其連線中支援重新連線旗標 - 如果設為 true,則在失去連線的情況下,客戶端會嘗試重新連線到伺服器,直到放棄為止。您現在可以在 database.yml 中為 MySQL 連線設定 reconnect = true,以從 Rails 應用程式取得此行為。預設為 false,因此現有應用程式的行為不會改變。

4.9 其他 Active Record 變更

  • 已從為 has_and_belongs_to_many 預載產生之 SQL 中移除多餘的 AS,讓它能更適用於某些資料庫。
  • 當遇到現有記錄時,ActiveRecord::Base#new_record? 現在會傳回 false,而非 nil
  • 已修正某些 has_many :through 關聯中,引號標示資料表名稱的錯誤。
  • 現在您可以為 updated_at 時間戳指定特定時間戳:cust = Customer.create(:name => "ABC Industries", :updated_at => 1.day.ago)
  • find_by_attribute! 呼叫失敗時,會傳回更佳的錯誤訊息。
  • Active Record 的 to_xml 支援功能變得更靈活,新增了 :camelize 選項。
  • 已修正從 before_updatebefore_create 取消回呼的錯誤。
  • 已新增透過 JDBC 測試資料庫的 Rake 任務。
  • validates_length_of 會使用自訂錯誤訊息,搭配 :in:within 選項(如果提供的話)。
  • 範圍選擇的計數現在運作正常,因此您可以執行諸如 Account.scoped(:select => "DISTINCT credit_limit").count 的動作。
  • ActiveRecord::Base#invalid? 現在會作為 ActiveRecord::Base#valid? 的相反動作。

5 Action Controller

Action Controller 在此版本中推出了一些重要的變更,包括改善呈現、路由和其他領域。

5.1 統一呈現

ActionController::Base#render 在決定要呈現什麼內容時,變得更聰明了。現在您只要告訴它要呈現什麼內容,就能期待獲得正確的結果。在較舊版本的 Rails 中,您通常需要提供明確的資訊才能呈現

render :file => '/tmp/random_file.erb'
render :template => 'other_controller/action'
render :action => 'show'

現在在 Rails 2.3 中,您只要提供您想呈現的內容即可

render '/tmp/random_file.erb'
render 'other_controller/action'
render 'show'
render :show

Rails 會根據要呈現的內容是否包含開頭斜線、內嵌斜線或完全沒有斜線,而選擇檔案、範本和動作。請注意,在呈現動作時,您也可以使用符號代替字串。其他呈現樣式 (:inline:text:update:nothing:json:xml:js) 仍需要明確選項。

5.2 應用程式控制器已重新命名

如果您一直對 application.rb 的特殊情況命名感到困擾,那麼您有福了!在 Rails 2.3 中,它已被重新設計為 application_controller.rb。此外,有一個新的 rake 任務 rake rails:update:application_controller 可以自動為您執行此操作,而且它會在一般的 rake rails:update 程序中執行。

5.3 HTTP Digest 驗證支援

Rails 現在內建支援 HTTP digest 驗證。若要使用它,請呼叫 authenticate_or_request_with_http_digest,並提供一個會傳回使用者密碼的區塊 (然後會對密碼進行雜湊,並與傳輸的憑證進行比較)

class PostsController < ApplicationController
  Users = {"dhh" => "secret"}
  before_filter :authenticate

  def secret
    render :text => "Password Required!"
  end

  private
  def authenticate
    realm = "Application"
    authenticate_or_request_with_http_digest(realm) do |name|
      Users[name]
    end
  end
end

5.4 更有效的路由

Rails 2.3 中有幾個重要的路由變更。formatted_ 路由輔助程式已消失,取而代之的是傳入 :format 作為選項。這將任何資源的路由產生程序減少 50%,而且可以節省大量的記憶體(在大型應用程式中最多可達 100MB)。如果你的程式碼使用 formatted_ 輔助程式,它仍然可以暫時運作,但該行為已不建議使用,而且如果使用新標準重寫這些路由,你的應用程式將會更有效率。另一個重大變更在於 Rails 現在支援多個路由檔案,而不再只有 routes.rb。你可以使用 RouteSet#add_configuration_file 隨時加入更多路由,而不用清除目前已載入的路由。雖然此變更對 Engines 最為有用,但你可以在任何需要批次載入路由的應用程式中使用它。

5.5 基於 Rack 的延遲載入 Session

一個重大的變更將 Action Controller session 儲存的基礎推向了 Rack 層級。這牽涉到程式碼中大量的變更,儘管對你的 Rails 應用程式來說應該是完全透明的(作為一個額外好處,舊 CGI session 處理程式中的一些棘手修補程式已被移除)。不過,由於一個簡單的原因,這仍然很重要:非 Rails Rack 應用程式可以存取與你的 Rails 應用程式相同的 session 儲存處理程式(因此也可以存取相同的 session)。此外,session 現在是延遲載入的(與框架其他部分的載入改善一致)。這表示如果你不需要 session,就不再需要明確停用它們;只要不參照它們,它們就不會載入。

5.6 MIME 類型處理變更

Rails 中處理 MIME 類型的程式碼有一些變更。首先,MIME::Type 現在實作 =~ 運算子,當你需要檢查具有同義詞的類型的存在時,這讓事情變得更簡潔

if content_type && Mime::JS =~ content_type
  # do something cool
end

Mime::JS =~ "text/javascript"        => true
Mime::JS =~ "application/javascript" => true

另一個變更在於框架現在在各種位置檢查 JavaScript 時使用 Mime::JS,這讓它可以乾淨地處理這些替代方案。

5.7 respond_to 的最佳化

Rails-Merb 團隊合併後的第一批成果,Rails 2.3 包含了 respond_to 方法的一些最佳化,這個方法當然在許多 Rails 應用程式中被大量使用,讓你的控制器可以根據傳入請求的 MIME 類型,以不同的格式來格式化結果。在消除了對 method_missing 的呼叫,並進行了一些剖析和調整後,我們看到在每秒處理請求的數量上,使用在三種格式間切換的簡單 respond_to,有 8% 的進步。最好的部分是什麼?你的應用程式程式碼完全不需要任何變更,就能享受到這個速度提升。

5.8 改善快取效能

Rails 現在會保留一個每個請求的本機快取,從遠端快取儲存中讀取,減少不必要的讀取並提升網站效能。雖然這項工作原本僅限於 MemCacheStore,但它對任何實作必要方法的遠端儲存都可用。

5.9 本土化檢視

Rails 現在可以提供本土化檢視,根據你設定的語言環境。例如,假設你有一個 Posts 控制器,帶有 show 動作。預設情況下,這會呈現 app/views/posts/show.html.erb。但如果你設定 I18n.locale = :da,它會呈現 app/views/posts/show.da.html.erb。如果沒有本土化的範本,會使用未裝飾的版本。Rails 也包含了 I18n#available_localesI18n::SimpleBackend#available_locales,它們會傳回一個陣列,其中包含目前 Rails 專案中可用的翻譯。

此外,你可以使用相同的架構來本土化 public 目錄中的救援檔案:例如 public/500.da.htmlpublic/404.en.html

5.10 翻譯的部分範圍

翻譯 API 的變更讓在部分範圍內撰寫主要翻譯變得更簡單且減少重複。如果你從 people/index.html.erb 範本呼叫 translate(".foo"),你實際上會呼叫 I18n.translate("people.index.foo")。如果你沒有在金鑰前面加上句點,那麼 API 就不會像以前一樣進行範圍設定。

5.11 其他 Action Controller 變更

  • ETag 處理已稍作整理:當回應中沒有主體或使用 send_file 傳送檔案時,Rails 現在會略過傳送 ETag 標頭。
  • Rails 會檢查 IP 欺騙這項事實對於與手機進行大量流量的網站來說可能會造成困擾,因為它們的代理程式通常不會正確設定。如果是這樣,你現在可以設定 ActionController::Base.ip_spoofing_check = false 以完全停用檢查。
  • ActionController::Dispatcher 現在實作它自己的中間件堆疊,你可以透過執行 rake middleware 來查看。
  • Cookie 會話現在具有持續性的會話識別碼,並與伺服器端儲存體具有 API 相容性。
  • 你現在可以使用符號作為 send_filesend_data:type 選項,如下所示:send_file("fabulous.png", :type => :png)
  • map.resources:only:except 選項不再由巢狀資源繼承。
  • 已將隨附的 memcached 用戶端更新為版本 1.6.4.99。
  • expires_instale?fresh_when 方法現在接受 :public 選項,以使其能與代理快取順利運作。
  • :requirements 選項現在可以與其他 RESTful 成員路由正常運作。
  • 淺層路由現在適當地尊重命名空間。
  • polymorphic_url 在處理具有不規則複數名稱的物件時有更好的表現。

6 Action View

Rails 2.3 中的 Action View 選取嵌套模型表單、對 render 的改進、更靈活的日期選取輔助提示,以及資產快取加速,還有其他功能。

6.1 嵌套物件表單

假設父模型接受子物件的嵌套屬性(如 Active Record 區段所討論),您可以使用 form_forfield_for 建立嵌套表單。這些表單可以任意深度嵌套,讓您可以在單一檢視中編輯複雜的物件階層,而不會有過多的程式碼。例如,假設有這個模型

class Customer < ActiveRecord::Base
  has_many :orders

  accepts_nested_attributes_for :orders, :allow_destroy => true
end

您可以在 Rails 2.3 中撰寫這個檢視

<% form_for @customer do |customer_form| %>
  <div>
    <%= customer_form.label :name, 'Customer Name:' %>
    <%= customer_form.text_field :name %>
  </div>

  <!-- Here we call fields_for on the customer_form builder instance.
   The block is called for each member of the orders collection. -->
  <% customer_form.fields_for :orders do |order_form| %>
    <p>
      <div>
        <%= order_form.label :number, 'Order Number:' %>
        <%= order_form.text_field :number %>
      </div>

  <!-- The allow_destroy option in the model enables deletion of
   child records. -->
      <% unless order_form.object.new_record? %>
        <div>
          <%= order_form.label :_delete, 'Remove:' %>
          <%= order_form.check_box :_delete %>
        </div>
      <% end %>
    </p>
  <% end %>

  <%= customer_form.submit %>
<% end %>

6.2 部分檢視的智慧化呈現

render 方法在這些年來變得更智慧,現在更智慧了。如果您有一個物件或集合和一個適當的部分檢視,而且命名相符,現在您可以只呈現物件,事情就會順利進行。例如,在 Rails 2.3 中,這些 render 呼叫會在您的檢視中運作(假設有明智的命名)

# Equivalent of render :partial => 'articles/_article',
# :object => @article
render @article

# Equivalent of render :partial => 'articles/_article',
# :collection => @articles
render @articles

6.3 日期選取輔助提示

在 Rails 2.3 中,您可以為各種日期選取輔助(date_selecttime_selectdatetime_select)提供自訂提示,就像您可以使用集合選取輔助一樣。您可以提供提示字串或個別提示字串的雜湊,用於各種元件。您也可以只將 :prompt 設定為 true,以使用自訂一般提示

select_datetime(DateTime.now, :prompt => true)

select_datetime(DateTime.now, :prompt => "Choose date and time")

select_datetime(DateTime.now, :prompt =>
  {:day => 'Choose day', :month => 'Choose month',
   :year => 'Choose year', :hour => 'Choose hour',
   :minute => 'Choose minute'})

6.4 AssetTag 時間戳快取

您可能熟悉 Rails 在靜態資源路徑中加入時間戳作為「快取破壞者」的做法。當您在伺服器上變更圖片和樣式表等項目時,這有助於確保不會從使用者的瀏覽器快取中提供過時的副本。現在,您可以使用 Action View 的 cache_asset_timestamps 設定選項修改此行為。如果您啟用快取,Rails 會在首次提供資源時計算時間戳並儲存該值。這表示提供靜態資源時會減少(昂貴的)檔案系統呼叫,但這也表示當伺服器正在執行時,您無法修改任何資源,並預期客戶端會採用變更。

6.5 資源主機作為物件

在 edge Rails 中,資源主機更具彈性,因為能夠將資源主機宣告為回應呼叫的特定物件。這讓您可以在資源主機中實作任何您需要的複雜邏輯。

6.6 grouped_options_for_select 輔助方法

Action View 已經有一堆輔助方法來協助產生選取控制項,但現在又多了一個:grouped_options_for_select。這個方法接受字串陣列或雜湊,並將它們轉換成包含在 optgroup 標籤中的 option 標籤字串。例如

grouped_options_for_select([["Hats", ["Baseball Cap","Cowboy Hat"]]],
  "Cowboy Hat", "Choose a product...")

傳回

<option value="">Choose a product...</option>
<optgroup label="Hats">
  <option value="Baseball Cap">Baseball Cap</option>
  <option selected="selected" value="Cowboy Hat">Cowboy Hat</option>
</optgroup>

6.7 表單選取輔助方法的已停用選項標籤

表單選取輔助方法(例如 selectoptions_for_select)現在支援 :disabled 選項,它可以採用單一值或陣列值,並在產生的標籤中停用

select(:post, :category, Post::CATEGORIES, :disabled => 'private')

傳回

<select name="post[category]">
<option>story</option>
<option>joke</option>
<option>poem</option>
<option disabled="disabled">private</option>
</select>

您也可以使用匿名函式在執行階段決定會從集合中選取和/或停用哪些選項

options_from_collection_for_select(@product.sizes, :name, :id, :disabled => lambda{|size| size.out_of_stock?})

6.8 有關範本載入的注意事項

Rails 2.3 包含針對任何特定環境啟用或停用快取範本的功能。快取範本可提升速度,因為它們在呈現時不會檢查新的範本檔案 - 但這也表示您無法在不重新啟動伺服器的狀況下「即時」取代範本。

在多數情況下,您會希望在生產環境中啟用範本快取,您可以在 production.rb 檔案中進行設定以執行此動作

config.action_view.cache_template_loading = true

在新的 Rails 2.3 應用程式中,這條指令會預設為您產生。如果您已從舊版 Rails 升級,Rails 會預設在生產和測試環境中快取範本,但不會在開發環境中快取範本。

6.9 其他 Action View 變更

  • CSRF 保護的權杖產生已簡化;現在 Rails 使用由 ActiveSupport::SecureRandom 產生的簡單隨機字串,而不是使用會話 ID。
  • auto_link 現在會適當地將選項(例如 :target:class)套用至產生的電子郵件連結。
  • autolink 輔助程式已重新編寫,使其較不雜亂且更直覺。
  • current_page? 現在即使 URL 中有多個查詢參數也能正常運作。

7 Active Support

Active Support 有些有趣的變更,包括導入 Object#try

7.1 Object#try

許多人已採用使用 try() 來嘗試對物件執行作業的觀念。它在檢視中特別有用,您可以在其中透過撰寫類似 <%= @person.try(:name) %> 的程式碼來避免 nil 檢查。現在,它已內建於 Rails 中。在 Rails 中實作時,它會對私有方法引發 NoMethodError,如果物件為 nil,它會永遠傳回 nil

7.2 Object#tap 回傳

Object#tapRuby 1.9 和 1.8.7 的新增功能,類似於 Rails 已經有段時間的 returning 方法:它讓位給一個區塊,然後回傳讓位的物件。Rails 現在包含程式碼,讓這項功能也能在舊版的 Ruby 中使用。

7.3 XMLmini 的可交換剖析器

Active Support 中的 XML 剖析支援變得更靈活,因為它允許你交換不同的剖析器。預設情況下,它使用標準的 REXML 實作,但如果你已經安裝了適當的 gem,你可以輕鬆地為自己的應用程式指定更快速的 LibXML 或 Nokogiri 實作

XmlMini.backend = 'LibXML'

7.4 TimeWithZone 的小數秒

TimeTimeWithZone 類別包含一個 xmlschema 方法,用於以 XML 友善的字串回傳時間。從 Rails 2.3 開始,TimeWithZone 支援與 Time 相同的引數,用於指定回傳字串的小數秒部分的位數

Time.zone.now.xmlschema(6) # => "2009-01-16T13:00:06.13653Z"

7.5 JSON 鍵號引號

如果你在「json.org」網站上查看規格,你會發現 JSON 結構中的所有鍵號都必須是字串,而且必須用雙引號引起來。從 Rails 2.3 開始,我們在此處執行正確的操作,即使是數值鍵號也是如此。

7.6 其他 Active Support 變更

  • 你可以使用 Enumerable#none? 檢查沒有任何元素與提供的區塊相符。
  • 如果您使用 Active Support 代理,新的 :allow_nil 選項讓您在目標物件為 nil 時傳回 nil,而非引發例外。
  • ActiveSupport::OrderedHash:現在實作 each_keyeach_value
  • ActiveSupport::MessageEncryptor 提供一種簡單的方法,用於加密資訊以儲存在不受信任的位置(例如 cookie)。
  • Active Support 的 from_xml 不再依賴 XmlSimple。相反地,Rails 現在包含自己的 XmlMini 實作,僅具備其所需的功用。這讓 Rails 得以捨棄一直隨身攜帶的 XmlSimple 捆綁副本。
  • 如果您將私人方法暫存,結果現在將會是私人的。
  • String#parameterize 接受一個選用的分隔符號:"Quick Brown Fox".parameterize('_') => "quick_brown_fox"
  • number_to_phone 現在接受 7 位數電話號碼。
  • ActiveSupport::Json.decode 現在處理 \u0000 樣式的跳脫序列。

8 Railties

除了上述涵蓋的 Rack 變更之外,Railties(Rails 本身的核心程式碼)具備許多重大變更,包括 Rails Metal、應用程式範本和安靜的回溯。

8.1 Rails Metal

Rails Metal 是一種新機制,可在您的 Rails 應用程式內提供超快速的端點。Metal 類別繞過路由和 Action Controller,以提供給您原始速度(當然是以 Action Controller 中的所有內容為代價)。這建立在所有近期基礎工作之上,以將 Rails 變成一個具有公開中介軟體堆疊的 Rack 應用程式。Metal 端點可以從您的應用程式或外掛程式載入。

8.2 應用程式範本

Rails 2.3 整合了 Jeremy McAnally 的 rg 應用程式產生器。這表示我們現在已將基於範本的應用程式產生器內建到 Rails 中;如果您有一組外掛程式要包含在每個應用程式中(還有許多其他使用案例),您只要設定一次範本,然後在執行 rails 指令時重複使用即可。還有一個 rake 任務可將範本套用至現有的應用程式

$ rake rails:template LOCATION=~/template.rb

這會將範本中的變更分層套用至專案已包含的任何程式碼之上。

8.3 更簡潔的回溯

Rails 2.3 採用 thoughtbot 的 Quiet Backtrace 外掛程式為基礎,讓您可以選擇性地從 Test::Unit 回溯中移除程式行,並在核心程式中實作 ActiveSupport::BacktraceCleanerRails::BacktraceCleaner。這支援篩選器(對回溯程式行執行基於正規表示式的替換)和靜音器(完全移除回溯程式行)。Rails 會自動加入靜音器,以消除新應用程式中最常見的雜訊,並建立一個 config/backtrace_silencers.rb 檔案來儲存您自己的新增內容。此功能也讓回溯中的任何寶石都能以更漂亮的格式列印。

8.4 透過延遲載入/自動載入,在開發模式中縮短開機時間

做了不少工作,以確保只有在實際需要時,才會將 Rails (及其相依性) 的位元帶入記憶體。核心架構 - Active Support、Active Record、Action Controller、Action Mailer 和 Action View - 現在使用 autoload 延遲載入其個別類別。這項工作應有助於降低記憶體使用量,並改善整體 Rails 效能。

您也可以指定 (使用新的 preload_frameworks 選項) 是否應在啟動時自動載入核心函式庫。這預設為 false,以便 Rails 自行逐一自動載入,但有些情況下您仍需要一次載入所有內容 - Passenger 和 JRuby 都希望看到所有 Rails 一起載入。

8.5 rake gem 任務改寫

各種 rake gem 任務的內部已大幅修改,以使系統能更妥善處理各種情況。gem 系統現在知道開發相依性和執行時期相依性的差異,具備更強健的解壓縮系統,在查詢 gem 狀態時提供更好的資訊,而且在您從頭開始導入時,較不容易出現「先有雞還是先有蛋」的相依性問題。此外,還修正了在 JRuby 下使用 gem 指令,以及相依性嘗試引入已供應的 gem 的外部副本的問題。

8.6 其他 Railties 變更

  • 已更新並擴充 CI 伺服器用於建置 Rails 的更新說明。
  • 已將 Rails 內部測試從 Test::Unit::TestCase 切換至 ActiveSupport::TestCase,而 Rails 核心需要 Mocha 才能測試。
  • 已整理預設的 environment.rb 檔案。
  • dbconsole 腳本現在讓您可以在不當機的情況下使用全數字密碼。
  • Rails.root 現在會傳回一個 Pathname 物件,這表示你可以直接使用它與 join 方法來 清理現有使用 File.join 的程式碼
  • /public 中處理 CGI 和 FCGI 分派的各種檔案不再預設產生於每個 Rails 應用程式(如果你需要它們,你仍然可以在執行 rails 指令時加入 --with-dispatchers 來取得它們,或稍後使用 rake rails:update:generate_dispatchers 來加入它們)。
  • Rails 指南已從 AsciiDoc 轉換為 Textile 標記。
  • 腳手架檢視和控制器已稍作清理。
  • script/server 現在接受一個 --path 參數,以從特定路徑掛載 Rails 應用程式。
  • 如果任何已設定的 gem 遺失,gem rake 任務將會略過載入大部分環境。這應該能解決許多「先有雞還是先有蛋」的問題,例如 rake gems:install 無法執行,因為 gem 遺失。
  • 現在會完全解開 gem 一次。這修正了 gem(例如 hoe)的問題,這些 gem 會以檔案的唯讀權限打包。

9 已棄用

此版本中已棄用一些較舊的程式碼

  • 如果你是一位(相當罕見的)Rails 開發人員,以一種依賴於 inspector、reaper 和 spawner 腳本的方式進行部署,你必須知道這些腳本不再包含在核心 Rails 中。如果你需要它們,你可以透過 irs_process_scripts 外掛程式取得副本。
  • render_component 在 Rails 2.3 中從「已棄用」變成「不存在」。如果你仍然需要它,你可以安裝 render_component 外掛程式
  • 已移除對 Rails 元件的支持。
  • 如果你習慣執行 script/performance/request 來檢視基於整合測試的效能,你需要學習一個新技巧:此指令碼現已從核心 Rails 中移除。有一個新的 request_profiler 外掛程式,你可以安裝它來取得完全相同的功能。
  • ActionController::Base#session_enabled? 已過時,因為現在會延遲載入階段。
  • protect_from_forgery:digest:secret 選項已過時且沒有作用。
  • 已移除一些整合測試輔助工具。response.headers["Status"]headers["Status"] 將不再傳回任何內容。Rack 不允許在回傳標頭中使用「狀態」。不過,你仍然可以使用 statusstatus_message 輔助工具。response.headers["cookie"]headers["cookie"] 將不再傳回任何 CGI Cookie。你可以檢查 headers["Set-Cookie"] 來查看原始 Cookie 標頭,或使用 cookies 輔助工具來取得傳送給客戶端的 Cookie 哈希。
  • formatted_polymorphic_url 已過時。請改用具有 :formatpolymorphic_url
  • ActionController::Response#set_cookie 中的 :http_only 選項已重新命名為 :httponly
  • to_sentence:connector:skip_last_comma 選項已由 :words_connector:two_words_connector:last_word_connector 選項取代。
  • 張貼一個包含空的 file_field 控制項的多部分表單,用於向控制器提交一個空字串。現在它會提交一個 nil,這是由於 Rack 的多部分解析器與舊的 Rails 解析器之間的差異所致。

10 個積分

發行說明由 Mike Gunderloy 編寫。此版本的 Rails 2.3 發行說明是根據 Rails 2.3 的 RC2 編寫的。

回饋

我們鼓勵您協助提升本指南的品質。

如果您發現任何錯字或事實錯誤,請協助修正。首先,您可以閱讀我們的 文件貢獻 章節。

您也可能會發現不完整的內容或未更新的內容。請務必為 main 新增任何遺漏的文件。請務必先查看 Edge Guides,以驗證問題是否已在 main 分支中修復。請查看 Ruby on Rails 指南指南,以了解樣式和慣例。

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

最後,歡迎在 官方 Ruby on Rails 論壇 上討論任何與 Ruby on Rails 文件相關的主題。