Rails 3.1 RC 發佈: 重點導覽

Update(2011/8/31): 正式釋出! Rails 3.1.0 has been released!

來整理一篇 Rails 3.1 重點,花了點時間看過一遍 Changelogs (TL;DR;)。

新的預設 jQuery

jQuery: New Default: 官方的說明

jQuery 取代 prototype.js 成為新的預設 JavaScript 函式庫。另外,RJS 也從核心中被移出成為 Plugin。還記得當年令人興奮的 RJS 功能,可以很方便的寫簡單的 Ajax 效果,如今又回到直接寫 JavaScript 才是王道。

Assets pipeline

RailsConf 2011, David Heinemeier Hansson: 今年 DHH 在 RailsConf 的演講,重點就在介紹 Assets pipeline。

靜態檔案成為一級公民了,Rails 3.1 透過 Sprockets 打包和壓縮靜態檔案,也支援編譯 SassCoffeeScript。細節請參考我書的 Assets 一章

將 CoffeeScript 納入預設有不少爭議,畢竟用 CoffeeScript 實在又多了學習負擔,不是這麼多人喜歡。不過它其實只是 Gemfile 預設載入的一行而已,如果不用拿掉即可。

HTTP Streaming

HTTP Streaming 功能是 Rails 3.1 的一個實驗性突破,可以在 render 樣板的同時,就同時開始下載資料來節省時間。原理是 HTTP 1.1 協定中的 Chunked transfer encoding 傳輸機制。我推薦可以看看 Facebook 的 BigPipe 應用其實就是這個技術。

這功能預設是關閉的,而且也不是打開設定就馬上可以享受到。因為 render 的流程不同了,本來可以先 render template 再套 layout 的,用 streaming 的話是改從 Layout 先開始,由上往下一行一吐出結果就丟給瀏覽器,因此需要搭配注意的細節不少,像是要用 Ruby 1.9、網頁伺服器要支援、template 中不能讀取 layout 中的變數、使用 provide helper 取代 content_for、Controller 的操作必須盡可能的改成 Lazy method (也就是真正耗時的動作得實際發生在 View 中,例如 SQL query,不然時間卡在 Action 裡沒進到 View 就沒辦法提早傳結果出去啦。好加在 ActiveRecord 的 Query 都已經是 Lazy method 了),最後所有你用到的 Rack Middleware 層都必須支援 HTTP Streaming,萬一其中有 Middleware 需要等 response 完整的 body 內容才能處理,那麼就會卡住而失去 Streaming 提早送資料給瀏覽器的意義。

Migration

Reversible migration:新的 change 方法可以不需要分開寫 up 跟 down 了,Rails 會自動對應出 down 的操作,猜不出來的時候才會要你補寫 down 方法。

還有,Migrations 內統一改用 Instance methods 而不是 class methods 了,寫 def up 和 def down 即可,不需要 def self.up 和 def self.down。

Rack::Cache

加入了 Rack-cache middleware ,搭配 #expires_in, #fresh_when, #stale with :public => true 等方法,並使用你設定的 Caching store 來存放資料 (例如memcached)。

注意到因為有了 Rack::Cache,原本 Controller 的 Page caching 被移除不需要了。

採用 Rack-caching 真正的重點倒不是在於增加效能,而是在於它讓你無痛就開始寫符合 HTTP caching 標準協定的程式,讓你之後有流量需求時,可以很彈性地轉換到真正的 HTTP caching 伺服器上,例如 Varnish。詳情請參考Rack-cache FAQ

Mountable Engines

Engine 被改的更為獨立,可以擁有獨立的 routes 和 namespace。請參考 API 文件,或是這篇簡介 Mountable engines in Rails 3.1 beta: getting started

ActiveRecord/ActiveModel 相關

  • 採用 SQL Prepared statements 了,增加複雜 SQL query 的效能。
  • Mass assignment 可以設定 attr_proected 和 attr_accessible 因應不同角色而有不同限制,挺不錯實用的功能。詳見 API 文件
  • Custom ActiveRecord Attribute Serialization: 支援不同的 Serialize 方式
  • ActiveRecord Identity Map:支援 Identity Map,相同的資料庫資料也一定會是同一個物件,可以節省資源增加一致性。不過因為行為有些改變,所以預設是關的,詳見
    API 文件
  • ActiveModel::SecurePassword,可以存密碼, 不過我覺得沒啥實用,大家都裝認證相關的 Gem 來用
  • 新的 update_column 方法,這會完全忽略 validations 和 callbacks。本來的 update_attribute 雖然會忽略 validations,但是會跑 callbacks。
  • ActionPack 相關

    • Template Inheritance: Controller 繼承也可以讓 Template 也繼承
    • force_ssl: 內建了 Rack::SSL middleware 可以限制整站必須是 SSL 存取。或是在 Controller 中用 force_ssl 這個方法限定部分 Actions 要用 SSL (之前大家是裝 ssl_requirement 這個 plugin。
    • ActionController::ParamsWrapper: 這功能讓 POST 可以直接傳 JSON 和 XML 資料並自動轉成 params hash 讓你使用,可以很方便寫出一致的 JSON/XML API 介面:吐資料和接收資料都用 JSON/XML。這功能預設是關的。

    ActionView 相關

    • form_for 的 :method 參數可以不必放 :html 裡面:也就是 form_for(@post, :html => { :method => :delete }) 變成 form_for(@post, :method => :delete)
    • 如果 form 裡面有用 file_field 檔案上傳,Rails 會自動幫 form_for 加上 :multipart => true 參數,這樣就不怕忘記啦,超棒。
    • 新增 j() helper 是 escape_javascript() 的別名
    • 新增 data 參數方便設定 HTML5 data-* 屬性:
      tag("div", :data => {:name => 'Stephen', :city_state => %w(Chicago IL)}) 會輸出 <div data-name="Stephen" data-city-state="["Chicago","IL"]" />

    其他

    • 在 rails console 中,改成預設會顯示 SQL query log。
    • CSS Sprites: DHH 去年 RailsConf 講過要有,很抱歉這次 3.1 沒有喔!! 這張票還沒兌現。

    Rails 3.2 ?

    展望未來,我想 Rails 有兩大開發重點方向:

    支援 Rich clients 的 API 介面

    @DHH 的 37Signals 用了 backbone.js 來做 Basecamp mobile 版。而 @wycats (Rails3 架構師) 加入了 SproutCore 團隊,今年他在 RailsConf 的演講 Building Rails Apps for the Rich Client 就在研究他們如何在 Rails 上設計 API 搭配 SproutCore。

    果然,這一篇 Rails core team 成員的
    A New World of Resources 透漏了他們打算從乏人問津的 ActiveResource 下手。看來設計出一套給 Rich clients (例如 JavaScript MVC 框架) 的 API Convention 慣例,會是下一個大目標。

    Middleware 大改造

    看完 RailsConf 2011: Aaron Patterson 的演講,你會發現要做 HTTP streaming 真的很難,所有 Rack Middleware 都要重新看過,因此 @tenderlove 提出了新的 Rack 介面計畫想要改寫。另外就是他發現 Rails 2 到 Rails 3 的 RPS 效能變差的主因是太多 Middleware 造成 call stack 太深了。Rails 2.3 有 51 deep、Rails 3.0 有 60 deep,到了 3.1 達到 67 deep。這也是他想要改進的地方。增加效能、節省記憶體使用量是 Rails 3.2 的一大目標。

    參與討論

    3 則留言

    1. 对于一个正在成长的框架来说,变动是最令开发者痛苦的地方,一升级不仅很多文档要改,还有很多观念都要改,对于正在学习的人们来说太痛苦了:(

    發佈留言

    發表迴響