Woooow~真的是好長一篇release note ,花了不少時間看過,順便作點摘要紀錄。第一個想法就是巨大的變革,大量的去耦合(decoupling),引入merb 2設計風格,幾乎是嶄新的架構。
回想當時第一次接觸到Ruby on Rails框架時還是1.2版呢,不知不覺3.0 Beta已經釋出,大概過了近四年吧!書架上還有DHH (David Heinemeier Hansson)的Agile Web Development with Rails第一版哩,只不過到現在也沒用RoR寫出啥像樣的應用程式,我想可能還是不夠投入,工作環境裡也無法讓我應用該技術,但我仍持續地關心。一想到好不容易習慣2.x版了,突然要轉換到3.0可能沒那麼簡單,等到正式釋出再到現有應用轉換升級可還有一大段路要走呢!
Upgrading to Rails 3
- 需要Ruby 1.8.7+
- 新的Rails Application物件
- 腳本script/* 換成 script/rails
- 套件依賴性改用bundler與Gemfile
“config.gem is dead, long live bundler” - 升級程序有外掛可協助 <= 沒試過
更詳細的升級說明文件。
Rails Architectural Changes
架構有六個主要的變更
- Railties 重構
- 所有主要的核心元件去耦合
- Active Model 抽象層
- Controller 抽象化
- Arel (Active Relation) 整合
- 郵件抽取 (Mail Extraction)
Railties
我不太懂這個字眼要怎樣解釋,在framework裡就好像是一根一根的支架,連接設定與各種元件。
- 每個應用程式現在豈有自己的名稱空間, 應用程式使用 YourAppName.boot 啟動,方便與其他應用程式溝通。
- 任何放在Rails.root/app下的程式都加入load path,所以你可以撰寫app/observers/user_observer.rb,Rails將會自動載入無須任何修改。
- Rails 3.0提供一個 Rails.config物件,提供集中式的設定選項貯存區域。
Railities generator也有大量的修改
- Generator完全重寫而且無法向下相容….Oops!!
- Rails template API 與 generator API 合併
- generator不再從特定路徑載入,只搜尋Ruby載入路徑,例如呼叫 rails generate foo 將尋找 generator/foo_generator。 ??
- 新的generator允許你覆寫樣板,放置副本到RAILS_ROOT/lib/templates目錄下。
- Rails::Generators::TestCase也被支援,所以你可以創建自己的generator並且測試它。
Railties generator產生的view也有些更動
- 不使用p標籤,改用div標籤
- Scaffold 使用 _form partial,避免 edit 與 new 畫面重複程式碼。
- Scaffold 表單現在使用 f.submit ,依照物件純入的狀態傳回 “Create ModelName” 或 “Update ModelName”字樣。
最後 rake tasks 也做了加強:
- 增加 rake db:forward,允許個別地向前啟用遷移檔。
- 增加 rake routes CONTROLLER=x,允許你只檢視特定controller的路由。
Railties現在廢止:
- RAILS_ROOT => Rails.root
- RAILS_ENV => Rails.env
- RAILS_DEFAULT_LOGGER => Rails.logger
PLUGIN/rails/tasks 與 PLUGIN/tasks 不再載入所有task,現在必須放到 PLUGIN/lib/tasks。
Internationalization
國際化使用最新的i18n gem,詳細的變動可以參考 Rails 3 I18n changes。多國語言在ruby 1.8 做得不是很好,而Rails國際化常用的第三方解決方案有Gettext或是Globalize。內建的I18n使用可參考ihower這篇,Globalize可參考國網中心這篇或是英文這篇。Globalize採用資料庫系統儲存翻譯字串,與目前OBW作法一樣,好處就是方便撰寫前端維護介面。國際化與地區化議題很龐大,一般小型應用程式要做到這塊並不容易,就以前開發軟體經驗,為了支援英日語系介面,只好請外面的翻譯公司協助,拿到翻譯搞後仍需反覆校對,若是允許客製修改的系統,客戶可能會挑你翻譯毛病,你還得教他怎麼改(凸顯彈性介面語系字串維護介面的必要性),或是幫他修改。更可怕的還有內容(資料面)的地區化呢!
Action Pack
學習RoR過程中遭遇最大挫折大概就是UI部份,這一向是我的罩門,JavaScript不熟,也不是很懂CSS與網頁設計,每每寫到顯示部份就頭疼。Rails 2.x內建的scaffold與helper還是過於基礎,對於進階的畫面控制你往往需要自行撰寫helper或使用AJAX,找現成的元件或他人的解決方案,很容易與原有畫面風格不搭配。我曾試著學習使用純JavaScript UI, like ExtJS,但過於費時反而降低開發效率,並不適合變動快速的企業需求(特別是台灣的中小企業!!),與個人或微小團隊,如果自己或成員都是geek級的或許沒有問題吧?
ActionView
文中說明大量改寫原有的Action View helpers,實現unobtrusive JavaScript,異動清單提示的都是小的便利性的變更,並沒令人驚豔的東西。啥??HTML 5 ?!我承認很先進,但我不懂>”<。可能我比較貪心,希望View Helper預設提供陽春的多重選擇器,樹狀元件等,這在目前公司的系統還挺常用的。
- You no longer need to call h(string) to escape HTML output, it is on by default in all view templates. If you want the unescaped string, call raw(string).
- Helpers now output HTML 5 by default.
- Form label helper now pulls values from I18n with a single value, so f.label :name will pull the :name translation.
- I18n select label on should now be :en.helpers.select instead of :en.support.select.
- You no longer need to place a minus sign at the end of a ruby interpolation inside an ERb template to remove the trailing carriage return in the HTML output.
- Added grouped_collection_select helper to Action View.
- Action View now will raise exceptions if CSS stylesheets and javascript files listed in the javascript_include_tag and stylesheet_include_tag helpers are missing.
- content_for? has been added allowing you to check for the existence of content in a view before rendering.
Active Model
這是個新玩意兒,特地從原來的ORM中切分出來,扮演了ORM的抽象層。以後如果要替原來的ActiveRecord寫擴充,改由實做Active Model介面。Yehuda Katz寫了一篇如何讓一般Ruby物件像ActiveRecord,說明了ORM抽象化與Action Pack介面的好處。
Validations
資料模型驗證一直是我非常欣賞ActiveRecord的地方,如今搬移到Active Model內,如此一般的物件也可以引用,又是去耦合帶來的好處。之前使用時覺得方法名稱又臭又長,例如 validates_numericality_of, validates_presence_of,經常記不住,加上選用參數又不太一樣,教人有些困擾。現在提供
簡便寫法,就好記許多。選項部份大致上差不多,容易理解。
:acceptance => Boolean
:confirmation => Boolean
:exclusion => { :in => Ennumerable }
:inclusion => { :in => Ennumerable }
:format => { :with => Regexp,n => :create }
:length => { :maximum => Fixnum }
:numericality => Boolean
:presence => Boolean
:uniqueness => Boolean
自訂驗證類別主要繼承ActiveMode::EachValidator,並撰寫validate_each(record, attribute, value)方法,放在lib下就會自動載入,透過名稱慣例很容易就可以在ActiveRecord類別中引用,參考一下範例應該不難理解。
Active Record
許多玩RoR大概都是被這個神奇套件吸引,我也不例外(成了Java叛徒!!)。查詢介面整合了名為Arel關聯技術(relational algebra),將令原來的查詢語法到了3.2後就不支援,例如以前可能會寫find(:first), find(:all),改成first與all。詳細的範例可參考這篇。
Patches and Deprecations
額外的修正最讓我注意的是大量的Oracle adapter的臭蟲修正,目前公司資料庫以Oracle為主軸,能不能正確地透過AR操作現有資料庫,是RoR被列入企業開發平台考量的重要關鍵。
A large amount of work done on the Oracle adapter as well with many bug fixes.
Active Resource
Active Resource也被抽離到Active Model。這部份大致上都是處理XML, JSON之類的,自己暫時用得較少,先前就算要提供給ExtJS的Json格式資料,也是透過ActiveRecord查詢結果轉換(to_json, to_ext_json),所以囉…
Active Support
這個套件本來就是一堆拉拉雜雜的輔助方法構成,因此3.0大改版當然也包括一堆細碎的修正,就不多說了,自己看吧。
Action Mailer
電子郵件在企業應用程式內大量使用,幾近氾濫,三不五時就發通知信,有員工遲到就發出勤異常通知,有帳款沒收回來也發催收信,連宿舍租約快到期都要發(不知道其他公司是不是也是這樣@@)。新的Action Mailer揚棄原有的TMail,使用新的Mail gem改寫API。『郵件類別集中到app/mailer資料夾』,管理起來應該比之前的直覺一點。
小結
Rails 3.0 修改幅度實在太大,這表示現有的插件可能都不能用了,未來考慮升級時,除了原本的程式碼翻寫,還得重新檢討選用的插件,如果是一個全新的開始,或許就不那麼痛苦了吧!?
註一:圖片與鍊結都是書本AWDR第三版