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

Ruby on Rails 4.1 版本說明

Rails 4.1 的重點

這些版本說明僅涵蓋重大變更。如需了解各種錯誤修正和變更,請參閱變更日誌或查看 GitHub 上 Rails 主要儲存庫中的提交清單

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/railsbin/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:uncommittedrake 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 :plainrender :htmlrender :body。(Pull Request / 更多詳細資料)

5 Action Mailer

請參閱 Changelog,以取得詳細變更。

5.1 值得注意的變更

  • 根據 37 Signals mail_view gem 新增郵件預覽功能。(提交

  • 設定 Action Mailer 訊息的產生。產生訊息所花費的時間會寫入記錄檔。(拉取請求

6 Active Record

有關詳細變更,請參閱 變更記錄

6.1 移除

  • 移除下列 SchemaCache 方法的過時 nil 傳遞:primary_keystablescolumnscolumns_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_updatespartial_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_classActiveRecord::Base.symbolized_sti_name,且不予取代。 Commit

6.3 顯著變更

  • 預設範圍不再被鏈結條件覆寫。

在此變更之前,當您在模型中定義 default_scope 時,它會被同一欄位中的鏈結條件覆寫。現在它會像任何其他範圍一樣合併。 更多詳細資訊

  • 已新增 ActiveRecord::Base.to_param,用於從模型屬性或方法衍生方便的「漂亮」網址。(Pull Request)

  • 新增 ActiveRecord::Base.no_touching,允許忽略模型上的觸發。(Pull Request)

  • 統一 MysqlAdapterMysql2Adapter 的布林型轉換。type_cast 會傳回 1 代表 true0 代表 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) 使用 LIMITed 查詢來擷取結果,而不是載入整個集合。(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_batchesfind_eachResult#eachEnumerable#index_by 現在會傳回一個 Enumerator,它可以計算其大小。(Pull Request

  • scopeenum 和關聯現在會針對「危險」名稱衝突引發例外狀況。(Pull RequestPull Request

  • secondfifth 方法會像 first 尋找器一樣運作。(Pull Request

  • touch 觸發 after_commitafter_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_changeschanges_appliedActiveModel::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_fallbackTime#utc_timeTime#local_time,建議使用 Time#utcTime#local

  • 移除已棄用的 Hash#diff,無替代品。

  • 移除已棄用的 Date#to_time_in_current_zone,建議使用 Date#in_time_zone

  • 移除已棄用的 Proc#bind,無替代品。

  • 移除已棄用的 Array#uniq_byArray#uniq_by!,建議改用原生 Array#uniqArray#uniq!

  • 移除已棄用的 ActiveSupport::BasicObject,建議改用 ActiveSupport::ProxyObject

  • 移除已棄用的 BufferedLogger,建議改用 ActiveSupport::Logger

  • 移除已棄用的 assert_presentassert_blank 方法,建議改用 assert object.blank?assert object.present?

  • 移除過濾物件的已棄用 #filter 方法,建議改用對應的方法(例如,對 before 過濾器使用 #before)。

  • 從預設的屈折變化中移除已棄用的 'cow' => 'kine' 不規則屈折變化。(提交

8.2 已棄用

8.3 值得注意的變更

  • ActiveSupport 的 JSON 編碼器已重新撰寫,以利用 JSON gem,而不是在純 Ruby 中執行自訂編碼。(Pull Request / 更多詳細資料)

  • 改善與 JSON gem 的相容性。(Pull Request / 更多詳細資料)

  • 已新增 ActiveSupport::Testing::TimeHelpers#travel#travel_to。這些方法會透過存根 Time.nowDate.today,將目前時間變更為指定的時間或持續時間。

  • 已新增 ActiveSupport::Testing::TimeHelpers#travel_back。此方法會移除 traveltravel_to 所新增的存根,將目前時間還原為原始狀態。(Pull Request)

  • 已新增 Numeric#in_milliseconds,例如 1.hour.in_milliseconds,因此我們可以將它們提供給 JavaScript 函式,例如 getTime()。(Commit)

  • 新增 Date#middle_of_dayDateTime#middle_of_dayTime#middle_of_day 方法。並新增 middaynoonat_middayat_noonat_middle_of_day 作為別名。(Pull Request)

  • 新增 Date#all_week/month/quarter/year 用於產生日期範圍。(Pull Request)

  • 新增 Time.zone.yesterdayTime.zone.tomorrow。(Pull Request)

  • 新增 String#remove(pattern) 作為 String#gsub(pattern,'') 常見模式的簡寫。(Commit)

  • 新增 Hash#compactHash#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 論壇 上進行。