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/rails
和 bin/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/
在 action 中回應變體,就像回應格式一樣
respond_to do |format|
format.html do |html|
html.tablet # renders 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 來查看電子郵件外觀的方法,該 URL 會渲染它們。
您實作一個預覽類別,其方法會傳回您想要檢查的郵件物件
class NotifierPreview < ActionMailer::Preview
def welcome
Notifier.welcome(User.first)
end
end
預覽在 https://127.0.0.1:3000/rails/mailers/notifier/welcome 中可用,而預覽清單在 https://127.0.0.1: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 # => Relation for all archived Conversations
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 並嘗試執行它以提取敏感資料。
這表示任何命中 .js
URL 的測試現在都會因為 CSRF 保護而失敗,除非它們使用 xhr
。請升級您的測試,使其明確預期 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:uncommitted
和rake test:recent
。
3.2 重大變更
依預設,現在為新的應用程式安裝 Spring 應用程式預載器。它使用
Gemfile
的開發群組,因此不會安裝在生產環境中。( Pull Request )BACKTRACE
環境變數,可顯示測試失敗的未篩選回溯追蹤。( Commit )將
MiddlewareStack#unshift
公開給環境設定。( Pull Request )新增
Application#message_verifier
方法以傳回訊息驗證器。( Pull Request )預設產生的測試輔助檔案所需的
test_help.rb
檔案,會自動使您的測試資料庫與db/schema.rb
(或db/structure.sql
) 保持同步。如果重新載入 schema 無法解決所有待處理的遷移,則會引發錯誤。您可以使用config.active_record.maintain_test_schema = false
來選擇不使用此功能。( Pull Request)引入
Rails.gem_version
作為一個方便的方法來返回Gem::Version.new(Rails.version)
,建議一種更可靠的方式來執行版本比較。( Pull Request)
4 Action Pack
請參考 變更日誌 以了解詳細的變更。
4.1 移除
移除用於整合測試的已棄用的 Rails 應用程式後備機制,請改為設定
ActionDispatch.test_app
。移除已棄用的
page_cache_extension
設定。移除已棄用的
ActionController::RecordIdentifier
,請改用ActionView::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
。( Pull Request)#url_for
接受一個包含選項的雜湊陣列。( Pull Request)新增
session#fetch
方法,其行為類似於 Hash#fetch,但例外的是,返回的值總是會被儲存到 session 中。( Pull Request)將 Action View 完全從 Action Pack 中分離出來。( Pull Request)
記錄哪些鍵受到深度 munging 的影響。( Pull Request)
新增設定選項
config.action_dispatch.perform_deep_munge
,可選擇不使用用於解決 CVE-2013-0155 安全漏洞的參數「深度 munging」。( Pull Request)新增設定選項
config.action_dispatch.cookies_serializer
,用於指定簽名和加密的 cookie jar 的序列化器。(Pull Requests 1, 2 / 更多詳細資訊)新增
render :plain
、render :html
和render :body
。( Pull Request / 更多詳細資訊)
5 Action Mailer
請參考 變更日誌 以了解詳細的變更。
5.1 值得注意的變更
新增基於 37 Signals mail_view gem 的 mailer 預覽功能。( Commit)
對 Action Mailer 訊息的產生進行檢測。產生訊息所需的時間會寫入日誌。( Pull Request)
6 Active Record
請參考 變更日誌 以了解詳細的變更。
6.1 移除
移除已棄用的將 nil 傳遞給以下
SchemaCache
方法:primary_keys
、tables
、columns
和columns_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_updates
、partial_updates?
和partial_updates=
。移除已棄用的方法
scoped
。移除已棄用的方法
default_scopes?
。移除 4.0 中已棄用的隱式 join 參考。
移除
activerecord-deprecated_finders
作為依賴項。有關更多資訊,請參閱 gem 的 README。移除
implicit_readonly
的使用。請明確使用readonly
方法將記錄標記為readonly
。( Pull Request)
6.2 棄用
棄用未在任何地方使用的
quoted_locking_column
方法。棄用
ConnectionAdapters::SchemaStatements#distinct
,因為內部不再使用它。( Pull Request)棄用
rake db:test:*
任務,因為測試資料庫現在會自動維護。請參閱 railties 發行說明。( Pull Request)棄用未使用的
ActiveRecord::Base.symbolized_base_class
和ActiveRecord::Base.symbolized_sti_name
,且不提供替代方案。 Commit
6.3 值得注意的變更
- 預設範圍不再被鏈式條件覆蓋。
在此變更之前,當您在模型中定義 default_scope
時,它會被同一個欄位中的鏈式條件覆蓋。現在它會像其他範圍一樣合併。 更多詳細資訊。
新增
ActiveRecord::Base.to_param
,方便從模型的屬性或方法衍生出「漂亮」的 URL。( Pull Request)新增
ActiveRecord::Base.no_touching
,允許忽略模型的 touch。( Pull Request)統一
MysqlAdapter
和Mysql2Adapter
的布林型別轉換。type_cast
將對true
返回1
,對false
返回0
。( 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)
fixture 檔案中的 ERB 不再於主要物件的上下文中求值。多個 fixture 使用的輔助方法應定義在包含於
ActiveRecord::FixtureSet.context_class
的模組中。( Pull Request)如果明確指定 RAILS_ENV,則不要建立或刪除測試資料庫。( Pull Request)
Relation
不再具有像是#map!
和#delete_if
之類的變更方法。在使用這些方法之前,請呼叫#to_a
轉換為Array
。( Pull Request)find_in_batches
、find_each
、Result#each
和Enumerable#index_by
現在會返回可以計算其大小的Enumerator
。( Pull Request)scope
、enum
和關聯現在會針對「危險」的名稱衝突引發錯誤。( Pull Request, Pull Request)second
到fifth
方法的行為類似於first
尋找器。( Pull Request)使
touch
觸發after_commit
和after_rollback
回呼。( Pull Request)為
sqlite >= 3.8.0
啟用部分索引。( Pull Request)使
change_column_null
可還原。( Commit)新增一個旗標,可在遷移後停用結構描述傾印。對於新應用程式,在生產環境中預設值為
false
。(Pull Request)
7 Active Model
請參閱 Changelog 以了解詳細變更。
7.1 棄用
- 棄用
Validator#setup
。現在應該在驗證器的建構子中手動完成。(Commit)
7.2 重要變更
在
ActiveModel::Dirty
中新增了新的 API 方法reset_changes
和changes_applied
,用於控制變更狀態。在定義驗證時,可以指定多個情境。(Pull Request)
attribute_changed?
現在接受雜湊來檢查屬性是否從或變更為給定值。(Pull Request)
8 Active Support
請參閱 Changelog 以了解詳細變更。
8.1 移除
移除了
MultiJSON
相依性。因此,ActiveSupport::JSON.decode
不再接受MultiJSON
的選項雜湊。(Pull Request / 更多細節)移除了用於將自訂物件編碼為 JSON 的
encode_json
鉤子的支援。此功能已提取到 activesupport-json_encoder gem 中。(相關 Pull Request / 更多細節)移除了已棄用的
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_fallback
、Time#utc_time
和Time#local_time
,改用Time#utc
和Time#local
。移除了已棄用的
Hash#diff
,沒有替代品。移除了已棄用的
Date#to_time_in_current_zone
,改用Date#in_time_zone
。移除了已棄用的
Proc#bind
,沒有替代品。移除了已棄用的
Array#uniq_by
和Array#uniq_by!
,請改用原生的Array#uniq
和Array#uniq!
。移除了已棄用的
ActiveSupport::BasicObject
,請改用ActiveSupport::ProxyObject
。移除了已棄用的
BufferedLogger
,請改用ActiveSupport::Logger
。移除了已棄用的
assert_present
和assert_blank
方法,請改用assert object.blank?
和assert object.present?
。移除了用於篩選物件的已棄用
#filter
方法,請改用相應的方法(例如,用於 before 篩選器的#before
)。從預設詞形變化中移除了 'cow' => 'kine' 不規則變化。(Commit)
8.2 棄用
棄用
Numeric#{ago,until,since,from_now}
,使用者應將值明確轉換為 AS::Duration,例如5.ago
=>5.seconds.ago
。(Pull Request)棄用 require 路徑
active_support/core_ext/object/to_json
。請改用active_support/core_ext/object/json
。(Pull Request)棄用
ActiveSupport::JSON::Encoding::CircularReferenceError
。此功能已提取到 activesupport-json_encoder gem 中。(Pull Request / 更多細節)棄用
ActiveSupport.encode_big_decimal_as_string
選項。此功能已提取到 activesupport-json_encoder gem 中。(Pull Request / 更多細節)棄用自訂
BigDecimal
序列化。(Pull Request)
8.3 重要變更
ActiveSupport
的 JSON 編碼器已重寫為利用 JSON gem,而不是在純 Ruby 中進行自訂編碼。(Pull Request / 更多細節)改善與 JSON gem 的相容性。(Pull Request / 更多細節)
新增
ActiveSupport::Testing::TimeHelpers#travel
和#travel_to
。這些方法透過存根Time.now
和Date.today
將目前時間變更為給定的時間或持續時間。新增
ActiveSupport::Testing::TimeHelpers#travel_back
。此方法會透過移除travel
和travel_to
新增的存根,將目前時間返回到原始狀態。(Pull Request)新增
Numeric#in_milliseconds
,例如1.hour.in_milliseconds
,以便我們可以將它們饋送到 JavaScript 函數,如getTime()
。(Commit)新增
Date#middle_of_day
、DateTime#middle_of_day
和Time#middle_of_day
方法。 也新增了midday
、noon
、at_midday
、at_noon
和at_middle_of_day
作為別名。(Pull Request)新增
Date#all_week/month/quarter/year
用於產生日期範圍。(Pull Request)新增
Time.zone.yesterday
和Time.zone.tomorrow
。(Pull Request)新增
String#remove(pattern)
作為String#gsub(pattern,'')
常見模式的簡寫。(Commit)新增
Hash#compact
和Hash#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 成為穩定且強大的框架。向他們所有人致敬。