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 相容的形式。- 已移除
CgiRequest
和CgiResponse
。 - 現在會延遲載入階段儲存。如果您在要求期間從未存取階段物件,它將永遠不會嘗試載入階段資料(剖析 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::AbstractRequest
和ActionController::Request
已統一。新的ActionController::Request
繼承自Rack::Request
。這會影響測試要求中對response.headers['type']
的存取。請改用response.content_type
。- 如果已載入
ActiveRecord
,ActiveRecord::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 的早期規劃。
- 更多資訊:Rails 文件專案
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? }
- 主要貢獻者:Eloy Duran
- 更多資訊:巢狀模型表單
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 上一樣)。在底層,巢狀交易是 使用儲存點,因此即使在沒有真正巢狀交易的資料庫上,也支援它們。還有一些神奇的事情發生,讓這些交易在測試期間與交易固定裝置配合良好。
- 主要貢獻者:Jonathan Viney 和 洪力來
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")
使用動態範圍不需要定義任何內容:它們只會運作。
- 主要貢獻者:Yaroslav Markin
- 更多資訊:Edge Rails 的新功能:動態範圍函式
4.4 預設範圍
Rails 2.3 將引入預設範圍的概念,類似於已命名範圍,但套用於模型中的所有已命名範圍或尋找函式。例如,您可以撰寫 default_scope :order => 'name ASC'
,而任何時候您從該模型中擷取記錄時,它們都會按名稱排序(除非您覆寫選項)。
- 主要貢獻者:Paweł Kondzior
- 更多資訊:Edge Rails 的新功能:預設範圍
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),您應只使用一般尋找方法搭配自己的迴圈。
- 更多資訊(在那個時間點,方便方法僅稱為
each
)
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_many
和 has_and_belongs_to_many
關聯中),用於在群組尋找中過濾記錄。正如那些有豐富 SQL 背景的人所知,這允許根據群組結果進行過濾
developers = Developer.find(:all, :group => "salary",
:having => "sum(salary) > 10000", :select => "salary")
- 主要貢獻者:Emilio Tagua
4.8 重新連接 MySQL 連線
MySQL 在其連線中支援重新連線旗標 - 如果設為 true,則在失去連線的情況下,客戶端會嘗試重新連線到伺服器,直到放棄為止。您現在可以在 database.yml
中為 MySQL 連線設定 reconnect = true
,以從 Rails 應用程式取得此行為。預設為 false
,因此現有應用程式的行為不會改變。
- 主要貢獻者:Dov Murik
- 更多資訊
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_update
或before_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
- 主要貢獻者:Gregg Kellogg
- 更多資訊:Edge Rails 的新功能:HTTP Digest 驗證
5.4 更有效的路由
Rails 2.3 中有幾個重要的路由變更。formatted_
路由輔助程式已消失,取而代之的是傳入 :format
作為選項。這將任何資源的路由產生程序減少 50%,而且可以節省大量的記憶體(在大型應用程式中最多可達 100MB)。如果你的程式碼使用 formatted_
輔助程式,它仍然可以暫時運作,但該行為已不建議使用,而且如果使用新標準重寫這些路由,你的應用程式將會更有效率。另一個重大變更在於 Rails 現在支援多個路由檔案,而不再只有 routes.rb
。你可以使用 RouteSet#add_configuration_file
隨時加入更多路由,而不用清除目前已載入的路由。雖然此變更對 Engines 最為有用,但你可以在任何需要批次載入路由的應用程式中使用它。
- 主要貢獻者:Aaron Batalion
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
,這讓它可以乾淨地處理這些替代方案。
- 主要貢獻者:Seth Fitzsimmons
5.7 respond_to
的最佳化
Rails-Merb 團隊合併後的第一批成果,Rails 2.3 包含了 respond_to
方法的一些最佳化,這個方法當然在許多 Rails 應用程式中被大量使用,讓你的控制器可以根據傳入請求的 MIME 類型,以不同的格式來格式化結果。在消除了對 method_missing
的呼叫,並進行了一些剖析和調整後,我們看到在每秒處理請求的數量上,使用在三種格式間切換的簡單 respond_to
,有 8% 的進步。最好的部分是什麼?你的應用程式程式碼完全不需要任何變更,就能享受到這個速度提升。
5.8 改善快取效能
Rails 現在會保留一個每個請求的本機快取,從遠端快取儲存中讀取,減少不必要的讀取並提升網站效能。雖然這項工作原本僅限於 MemCacheStore
,但它對任何實作必要方法的遠端儲存都可用。
- 主要貢獻者:Nahum Wild
5.9 本土化檢視
Rails 現在可以提供本土化檢視,根據你設定的語言環境。例如,假設你有一個 Posts
控制器,帶有 show
動作。預設情況下,這會呈現 app/views/posts/show.html.erb
。但如果你設定 I18n.locale = :da
,它會呈現 app/views/posts/show.da.html.erb
。如果沒有本土化的範本,會使用未裝飾的版本。Rails 也包含了 I18n#available_locales
和 I18n::SimpleBackend#available_locales
,它們會傳回一個陣列,其中包含目前 Rails 專案中可用的翻譯。
此外,你可以使用相同的架構來本土化 public 目錄中的救援檔案:例如 public/500.da.html
或 public/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_file
和send_data
的:type
選項,如下所示:send_file("fabulous.png", :type => :png)
。 map.resources
的:only
和:except
選項不再由巢狀資源繼承。- 已將隨附的 memcached 用戶端更新為版本 1.6.4.99。
expires_in
、stale?
和fresh_when
方法現在接受:public
選項,以使其能與代理快取順利運作。:requirements
選項現在可以與其他 RESTful 成員路由正常運作。- 淺層路由現在適當地尊重命名空間。
polymorphic_url
在處理具有不規則複數名稱的物件時有更好的表現。
6 Action View
Rails 2.3 中的 Action View 選取嵌套模型表單、對 render
的改進、更靈活的日期選取輔助提示,以及資產快取加速,還有其他功能。
6.1 嵌套物件表單
假設父模型接受子物件的嵌套屬性(如 Active Record 區段所討論),您可以使用 form_for
和 field_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_select
、time_select
和 datetime_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'})
- 主要貢獻者:Sam Oliver
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 表單選取輔助方法的已停用選項標籤
表單選取輔助方法(例如 select
和 options_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
。
- 更多資訊:try()
7.2 Object#tap 回傳
Object#tap
是 Ruby 1.9 和 1.8.7 的新增功能,類似於 Rails 已經有段時間的 returning
方法:它讓位給一個區塊,然後回傳讓位的物件。Rails 現在包含程式碼,讓這項功能也能在舊版的 Ruby 中使用。
7.3 XMLmini 的可交換剖析器
Active Support 中的 XML 剖析支援變得更靈活,因為它允許你交換不同的剖析器。預設情況下,它使用標準的 REXML 實作,但如果你已經安裝了適當的 gem,你可以輕鬆地為自己的應用程式指定更快速的 LibXML 或 Nokogiri 實作
XmlMini.backend = 'LibXML'
- 主要貢獻者:Bart ten Brinke
- 主要貢獻者:Aaron Patterson
7.4 TimeWithZone 的小數秒
Time
和 TimeWithZone
類別包含一個 xmlschema
方法,用於以 XML 友善的字串回傳時間。從 Rails 2.3 開始,TimeWithZone
支援與 Time
相同的引數,用於指定回傳字串的小數秒部分的位數
Time.zone.now.xmlschema(6) # => "2009-01-16T13:00:06.13653Z"
- 主要貢獻者:Nicholas Dainty
7.5 JSON 鍵號引號
如果你在「json.org」網站上查看規格,你會發現 JSON 結構中的所有鍵號都必須是字串,而且必須用雙引號引起來。從 Rails 2.3 開始,我們在此處執行正確的操作,即使是數值鍵號也是如此。
7.6 其他 Active Support 變更
- 你可以使用
Enumerable#none?
檢查沒有任何元素與提供的區塊相符。 - 如果您使用 Active Support 代理,新的
:allow_nil
選項讓您在目標物件為 nil 時傳回nil
,而非引發例外。 ActiveSupport::OrderedHash
:現在實作each_key
和each_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
這會將範本中的變更分層套用至專案已包含的任何程式碼之上。
- 主要貢獻者:Jeremy McAnally
- 更多資訊:Rails 範本
8.3 更簡潔的回溯
Rails 2.3 採用 thoughtbot 的 Quiet Backtrace 外掛程式為基礎,讓您可以選擇性地從 Test::Unit
回溯中移除程式行,並在核心程式中實作 ActiveSupport::BacktraceCleaner
和 Rails::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 的外部副本的問題。
- 主要貢獻者:David Dollar
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 不允許在回傳標頭中使用「狀態」。不過,你仍然可以使用status
和status_message
輔助工具。response.headers["cookie"]
和headers["cookie"]
將不再傳回任何 CGI Cookie。你可以檢查headers["Set-Cookie"]
來查看原始 Cookie 標頭,或使用cookies
輔助工具來取得傳送給客戶端的 Cookie 哈希。 formatted_polymorphic_url
已過時。請改用具有:format
的polymorphic_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 文件相關的主題。