1 應用程式架構
Rails 應用程式的架構有兩個主要變更:完全整合 Rack 模組化網頁伺服器介面,以及更新的 Rails Engines 支援。
1.1 Rack 整合
Rails 現在已擺脫其 CGI 的過去,並在各處使用 Rack。 這需要並導致大量的內部變更(但如果您使用 CGI,請不用擔心;Rails 現在透過 Proxy 介面支援 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、從記憶體快取載入資料或查詢 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 Engines 支援
經過幾個版本沒有升級後,Rails 2.3 為 Rails Engines(可以嵌入其他應用程式中的 Rails 應用程式)提供了一些新功能。 首先,引擎中的路由檔案現在會自動載入和重新載入,就像您的 routes.rb
檔案一樣(這也適用於其他外掛程式中的路由檔案)。 其次,如果您的外掛程式具有應用程式資料夾,則 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 支援
無論您是在 Ruby 1.8 還是現在發布的 Ruby 1.9.1 上執行,Rails 2.3 都應該通過所有自己的測試。 不過,您應該注意,移至 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 的情況)。在底層,巢狀交易是使用儲存點 (savepoints),因此即使在沒有真正巢狀交易的資料庫上也能支援。還有一點額外的處理,以使這些交易在測試期間能與交易 fixture 良好配合。
- 主要貢獻者:Jonathan Viney 和 Hongli Lai
4.3 動態範圍 (Dynamic Scopes)
你可能知道 Rails 中的動態查找器 (dynamic finders) (允許你即時創建像 find_by_color_and_flavor
這樣的方法),以及具名範圍 (named scopes) (允許你將可重複使用的查詢條件封裝成友好的名稱,如 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 預設範圍 (Default Scopes)
Rails 2.3 將引入與具名範圍相似的預設範圍的概念,但它適用於模型內的所有具名範圍或查找方法。例如,你可以寫 default_scope :order => 'name ASC'
,這樣任何時候你從該模型檢索記錄時,它們都會按名稱排序 (當然,除非你覆蓋此選項)。
- 主要貢獻者:Paweł Kondzior
- 更多資訊:Edge Rails 的新功能:預設範圍
4.5 批次處理 (Batch Processing)
現在你可以使用 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 回呼的多重條件 (Multiple Conditions for Callbacks)
在使用 Active Record 回呼時,你現在可以在同一個回呼上組合 :if
和 :unless
選項,並將多個條件作為陣列提供。
before_save :update_credit_rating, :if => :active,
:unless => [:admin, :cash_only]
- 主要貢獻者:L. Caviola
4.7 使用 having 進行查找 (Find with having)
Rails 現在在 find 上 (以及在 has_many
和 has_and_belongs_to_many
關聯上) 具有 :having
選項,用於篩選分組查找中的記錄。正如那些具有深厚 SQL 背景的人所知,這允許根據分組結果進行篩選。
developers = Developer.find(:all, :group => "salary",
:having => "sum(salary) > 10000", :select => "salary")
- 主要貢獻者:Emilio Tagua
4.8 重新連接 MySQL 連線 (Reconnecting MySQL Connections)
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 統一渲染 (Unified Rendering)
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 Controller Renamed)
如果你是那些一直對 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 更有效率的路由 (More Efficient Routing)
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,你不再需要明確停用 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 目錄中的 rescue 檔案:例如,public/500.da.html
或 public/404.en.html
也能運作。
5.10 部分翻譯範圍
翻譯 API 的變更使得在 partial 中編寫鍵值翻譯變得更容易且減少重複。如果您從 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
現在實作了自己的 middleware 堆疊,您可以透過執行rake middleware
來查看。- Cookie sessions 現在具有持久的 session 識別碼,與伺服器端儲存具有 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.checkbox :_delete %>
</div>
<% end %>
</p>
<% end %>
<%= customer_form.submit %>
<% end %>
6.2 Partial 的智慧渲染
多年來,render 方法變得越來越聰明,現在更是如此。如果您有一個物件或集合以及一個適當的 partial,而且命名一致,您現在可以直接渲染物件,事情就會運作。例如,在 Rails 2.3 中,這些渲染呼叫將在您的視圖中運作(假設合理的命名)
# 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 已經有一堆輔助器來協助產生 select 控制項,但現在又多了一個: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 表單選擇輔助器的 disabled 選項標籤
表單選擇輔助器(例如 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
產生的簡單隨機字串,而不是與 session ID 混淆。 auto_link
現在可以正確地將選項(例如:target
和:class
)套用到產生的電子郵件連結。autolink
輔助器已重構,使其稍微不雜亂且更直覺。- 即使 URL 中有多個查詢參數,
current_page?
現在也能正常運作。
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 Backport
Object#tap
是 Ruby 1.9 和 1.8.7 的新增功能,它類似於 Rails 一直以來擁有的 returning
方法:它會產生一個區塊,然後傳回所產生的物件。Rails 現在包含程式碼,讓這也可以在較舊版本的 Ruby 中使用。
7.3 XMLmini 的可交換解析器
Active Support 中對 XML 解析的支援已變得更加靈活,允許您換入不同的解析器。預設情況下,它使用標準的 REXML 實作,但是您可以輕鬆地為自己的應用程式指定更快的 LibXML 或 Nokogiri 實作,前提是您已安裝了適當的 gem
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 捆綁副本。 - 如果你將一個私有方法記憶化(memoize),結果現在會是私有的。
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 更安靜的回溯追蹤
在 thoughtbot 的 Quiet Backtrace 外掛程式的基礎上,該外掛程式允許您有選擇性地從 Test::Unit
回溯追蹤中移除行,Rails 2.3 在核心中實作了 ActiveSupport::BacktraceCleaner
和 Rails::BacktraceCleaner
。這支援過濾器(對回溯追蹤行執行基於正則表達式的替換)和靜音器(完全移除回溯追蹤行)。Rails 會自動新增靜音器來消除新應用程式中最常見的雜訊,並建立一個 config/backtrace_silencers.rb
檔案來保存您自己的新增項目。此功能還能從回溯追蹤中的任何 gem 更漂亮地列印。
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 命令的問題,以及解決嘗試引入已 vendor 的 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
的現有程式碼。- 預設情況下,不再在每個 Rails 應用程式中產生 /public 中處理 CGI 和 FCGI 分發的各種檔案(如果您需要在執行
rails
指令時新增--with-dispatchers
,或稍後使用rake rails:update:generate_dispatchers
新增它們,您仍然可以取得它們)。 - Rails 指南已從 AsciiDoc 轉換為 Textile 標記。
- 已稍微清理 scaffolded 檢視和控制器。
script/server
現在接受--path
引數,以從特定路徑掛載 Rails 應用程式。- 如果遺失任何設定的 gem,gem rake 任務將跳過載入大部分環境。這應可解決許多「雞生蛋還是蛋生雞」的問題,其中 rake gems:install 因為遺失 gem 而無法執行。
- gem 現在只解壓縮一次。這修復了 gem(例如 hoe)的問題,這些 gem 的檔案是以唯讀權限打包的。
9 已棄用
在此版本中,一些較舊的程式碼已棄用
- 如果您是少數(相當罕見)以依賴檢查器、收割機和產生器指令碼的方式部署的 Rails 開發人員之一,則需要知道這些指令碼不再包含在 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
和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
控制項張貼 multipart 表單過去會將空字串提交到控制器。現在,由於 Rack 的 multipart 分析器與舊 Rails 分析器之間的差異,它會提交一個 nil。
10 貢獻者
版本說明由 Mike Gunderloy 編譯。此版本的 Rails 2.3 版本說明是根據 Rails 2.3 的 RC2 編譯的。