1 升級至 Rails 4.1
如果您要升級現有的應用程式,在開始之前,最好先做好測試範圍。如果您尚未升級到 Rails 4.0,您也應該先升級到 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/
就像回應格式一樣,在動作中回應變體
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 來查看電子郵件的外觀。
您實作一個預覽類別,其方法傳回您想要檢查的郵件物件
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。請改用明確的 xhr :post, :create, format: :js
,而不是 post :create, format: :js
。
3 Railties
請參閱 變更日誌,以取得詳細變更。
3.1 移除
已移除
update:application_controller
rake 任務。已移除已棄用的
Rails.application.railties.engines
。已移除已棄用的
threadsafe!
,取而代之的是 Rails Config。已移除已棄用的
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`)讓您的測試資料庫保持最新狀態。如果重新載入架構無法解決所有未完成的遷移,它會引發錯誤。使用 `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
方法,fetch 的行為類似於 Hash#fetch,但例外的是,傳回的值總是會儲存到 session 中。(Pull Request)將 Action View 完全從 Action Pack 分離出來。(Pull Request)
記錄哪些金鑰受到深度修改的影響。(Pull Request)
新的設定選項
config.action_dispatch.perform_deep_munge
,用於停用參數「深度修改」,這項修改用於解決安全性漏洞 CVE-2013-0155。(Pull Request)新的設定選項
config.action_dispatch.cookies_serializer
,用於指定簽署和加密 cookie jar 的序列化器。(Pull Request 1, 2 / 更多詳細資料)新增
render :plain
、render :html
和render :body
。(Pull Request / 更多詳細資料)
5 Action Mailer
請參閱 Changelog,以取得詳細變更。
5.1 值得注意的變更
6 Active Record
有關詳細變更,請參閱 變更記錄。
6.1 移除
移除下列
SchemaCache
方法的過時 nil 傳遞: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 中已棄用的隱式聯結參考。
已移除
activerecord-deprecated_finders
作為依賴項。有關更多資訊,請參閱 寶石 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
,用於從模型屬性或方法衍生方便的「漂亮」網址。(Pull Request)新增
ActiveRecord::Base.no_touching
,允許忽略模型上的觸發。(Pull Request)統一
MysqlAdapter
和Mysql2Adapter
的布林型轉換。type_cast
會傳回1
代表true
,0
代表false
。(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
ed 查詢來擷取結果,而不是載入整個集合。(Pull Request)inspect
在 Active Record 模型類別上不會啟動新的連線。這表示當資料庫遺失時,呼叫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_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
請參閱 變更記錄,以取得詳細變更內容。
7.1 已棄用
- 已棄用
Validator#setup
。現在應該在驗證器的建構函式中手動執行此動作。(Commit)
7.2 顯著變更
已新增新的 API 方法
reset_changes
和changes_applied
到ActiveModel::Dirty
,用於控制變更狀態。在定義驗證時,能夠指定多個內容。(Pull Request)
attribute_changed?
現在接受雜湊,用於檢查屬性是否從給定的值變更為:from
和/或:to
。(Pull Request)
8 Active Support
請參閱 變更記錄,以取得詳細變更內容。
8.1 已移除
已移除
MultiJSON
相依性。因此,ActiveSupport::JSON.decode
不再接受MultiJSON
的選項雜湊。(Pull Request / 更多詳細資料)移除用於將自訂物件編碼成 JSON 的
encode_json
鉤子支援。此功能已萃取至 activesupport-json_encoder 寶石中。(相關 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' 不規則屈折變化。(提交)
8.2 已棄用
已棄用
Numeric#{ago,until,since,from_now}
,使用者預期會將值明確轉換成 AS::Duration,例如5.ago
=>5.seconds.ago
(Pull Request)已棄用需要路徑
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,使其成為穩定且強大的框架。向所有這些人致敬。
回饋
我們鼓勵您協助提升本指南的品質。
如果您發現任何錯字或事實錯誤,請貢獻您的意見。要開始,您可以閱讀我們的 文件貢獻 部分。
您也可能會發現內容不完整或不是最新資訊。請務必為 main 新增任何遺失的文件。請務必先查看 Edge Guides,以驗證問題是否已在主分支中修復。查看 Ruby on Rails 指南指南 以了解樣式和慣例。
如果出於任何原因,您發現需要修復但無法自行修補,請 開啟問題。
最後但並非最不重要的一點,任何有關 Ruby on Rails 文件的討論都非常歡迎在 官方 Ruby on Rails 論壇 上進行。