天天看點

師傅領錯門,害了你個人 - ruby/rails新手避免入錯門

最近看到一位Ruby On Rails新手寫的代碼,簡直是慘不忍睹,問了一下他竟然是用李剛寫的那本<<Ruby on Rails靈活開發最佳實踐>>作為入門材料的,偶真是faint,啥也不多說了,為了讓更多的Ruby On Rails的新手避免走彎路,偶覺得很有必要來評論一下這本書,以china pub上下載下傳的第15章樣章為例子:

[url]http://www.china-pub.com/39348[/url]

這章是講一個注冊使用者通過郵件注冊激活的例子,偶們來看看所謂的最佳實踐實際是如何成為絕佳反面教材:

1. 建立一個使用者表

這裡使用的是sql,而不是Rails最佳實踐推薦的migration

2. 使用者表中直接用明碼儲存使用者的密碼

請各位作實際開發新手注意:任何一個應用都不應該犯這樣愚蠢的錯誤

3. 标示使用者是否激活的字段名叫is_actived

這不符合rails的最佳實踐寫法,對于boolean類型的資料,應該省略前面的is_,ActiveRecord會自動加個?号,映射成actived?

4. User模型的校驗功能用errors.add這樣手工的方法

最佳實踐是使用Validation DSL,除非ActiveRecord提供的DSL不能滿足你的特殊校驗需求,否則毫無必要自己手工處理

就算你有很特殊的校驗需求,在這段代碼裡面也應該使用errors.add_to_base,而不是用errors.add_base,跟一個空白的字元串

5. 設定使用者的預設激活為false:@user.is_activated = false

Rails的理念是COC和DRY,這種初始預設值的設定應該在建立資料庫定義的時候指定,而且預設的boolean都是false,這裡的指派完全是多此一舉

讓我們先休息和回顧一下,上面提到的5個絕佳反面教材竟然是出現在一個章節中的一個小段:15.4.1基本注冊功能,錯誤之密集真是令人咋舌。

如果你和偶一樣,還能忍受下去,恭喜你,你具備了給爛代碼作Code Review的基本要求:[color=red]耐力[/color]。

偶們來繼續往下看:

6. 看看發送郵件的代碼

@sent_on指定的是郵件頭資訊中的Date,預設就是使用目前時間,這裡的指派也是多此一舉

@headers指定的是郵件頭資訊的hash,這裡也是也是多此一舉

結合之前的問題5,李剛老師您這是用無用代碼來充書本厚度麼?

7. if user != nil && user.is_activated == false

user.is_activated == false ??? 這叫啥代碼阿? 偶的天哪,李剛老師可能是為了保持風格統一,後面果然還有 user.is_activated == true ,這是偶看到搞笑的代碼了...

8. pro_activate Action的代碼寫得及其冗長

綜合前面的錯誤,偶想李剛可能壓根不懂一些ruby和rails的慣用法,偶好為人師一下,符合ruby風格的代碼應該是這樣:

而且在實際開發中,作為最佳實踐,最後一個else判斷完全是不必要的,大家可以想想什麼情況下會出現跑到最後一個else?嗯,隻有在惡意構造url攻擊的情況下,這樣我們完全可以改成:

User.find_by_name_and_active_code_and_active(params[:name], params[:active_code], false)

在之後的pro_login action裡面的代碼就不多說了,和前面一樣,也有user != nil && user.is_activated == false這樣搞笑的代碼出現。

看完了這個短短5頁的樣章中有那麼多的錯誤,偶明白了為什麼那個新手寫的代碼是如此的慘不忍睹,雖然俗話說,師傅領進門,修行在個人,但是也要曉得:師傅領錯門,害了你個人

最後推薦了另外幾本Ruby和Rails的書給他,讓他好好改造去了...