over 3 years ago

前陣子我在 RubyConfChina 2013 的 Talk:Maintainable Rails View

現在已經重新整理成一本書 Maintainable Rails View https://leanpub.com/rails-view-book

當初會整理這個 Talk 和書的原因是是因為長久以來:相對於 View,在一個 Project 裡面,設計出乾淨的 Model 與 Controller,是相對簡單的。但事情一跑到 View,就會變得相當複雜。很難有一個基礎簡單的思路去整理這些糾結的線條。

所以我最後決定釋出一份這樣的整理指南。

這其實也是我們 Rocodev 目前在用的 Rails View 整理技巧。

這本書包含以下幾個主題:

  • Helper 使用時機
  • Helper Best Pratices
  • Partial 使用時機
  • Partial Best Pratices
  • Helper 與 Partial 之外的整理武器
  • Object-Oriented View

共有十八個技巧。定價是 20 USD。

新書上架,提供折價卷:rubyconfchina2013 (折價 5USD 至 2013/12/01)

其他

曾經購買 Essential Rails Pattern 的舊讀者,我後來考慮這本書的架構太龐大。之後應該會分拆成幾本書。原書則不再更新。我會寄一個 Maintainable Rails View 完全免費的 coupon 給你們。(屆時請查看你們的電子信箱)

有讀者問到與之前的文章系列的不同。這本書部分內容是重新寫過並且編排的。有關於 Object Oriented View 的部份本月底也會翻新(新增更多 code example)。

 
over 3 years ago

Summary

總結以上 18 個設計手法,看似複雜,其實原則不外乎:

  • Always assume things need to be decorated (永遠假設東西必須要被裝飾)
  • Extract logic into methods / classes ( 將邏輯封裝成 method 或者 class )
  • Avoid perform query in view/helper ( 盡量避免在 view/helper 裡面進行資料查詢 )
  • When things get complicated, build a new control center (當事情變得複雜,不要拘泥於舊的手段,找一個新的中心重新整理控制)

掌握這些原則,就可以儘量把 View 整理的乾乾淨淨。

Read on →
 
over 3 years ago

這一篇的重點也是 Object-Oriented View。因為篇幅太長所以再拆一篇。

16. Form Builder

有時候我們為了排版 Form,不得不在 Form 裡面也穿插一些 HTML 作 styling。

<%= form_for @user do |form| %>
  <div class="field">
    <%= form.label :name %>
    <%= form.text_field :name %>
  </div>

  <div class="field">
    <%= form.label :email %>
    <%= form.text_field :email %>
  </div>
<% end %>

但要寫十幾遍 <div class="field"> 是一件很煩人的事。我們最希望的是,其實 View 裡面只要這樣寫就 OK 了:

<%= form_for @user, :builder => HandcraftBuilder do |form| %>
  <%= form.custom_text_field :name %>
  <%= form.custom_text_field :email %>
<% end %>

這樣的煩惱可以透過客製 Form Builder 解決:

Read on →
 
over 3 years ago

這一篇的重點是 Object-Oriented View。

14. Decorate using Decorator ( don’t put everything in model )

在前面我們介紹了幾個手法,包括 將 Logic 收納到 Helper 裡面

def render_article_publish_status(article)
  if article.published?
    "Published at #{article.published_at.strftime('%A, %B %e')}"
  else
    "Unpublished"
  end
end

以及 將 Helper 裡面的 Logic 重新整理到 Model

Read on →
 
over 3 years ago

這一篇的重點是除了 Helper 和 Partial 外,還有什麼工具是可以拿來用來整理 View 的。

11. content_for ( yield )

有些開發者不是很了解 Rails 的 yield 是拿來作什麼的。你可以理解成 跳躍到定點執行

這招常被用在一個情景上: Best Practices for Speeding Up Your Web Site 中的 put javascript at bottom。

在調整前端 performance 時,最常見也最有效的一招就是,把肥大的 JavaScript 放在最底端讀入執行,因為很多 JS 都是 document.ready 才會被執行。

但是,如果開發者只是把 javascript_include_tag 丟到 view 的底下,如:

Read on →
 
over 3 years ago

這一篇的重點是 Partial 的設計

7. Move code to Partial

什麼時候應該將把程式碼搬到 Partial 呢?

  • long template | code 超過兩頁請注意
  • highly duplicated | 內容高度重複
  • indepdenent blocks | 可獨立作為功能區塊

常見情境:

  • nav/user_info
  • nav/admin_menu
  • vendor_js/google_analytics
  • vendor_js/disqus_js
  • global/footer

8. Use presenter to clean the view ( 使用 Presenter 解決 logic in view 問題)

在前一章節,我們介紹過 view 裡面常被迫出現這種 code

Read on →
 
over 3 years ago

這篇是我在 RubyConfChina 2013 的 Talk:Maintainable Rails View

當初會整理這個 Talk 的原因是因為長久以來:相對於 View,在一個 Project 裡面,設計出乾淨的 Model 與 Controller,是相對簡單的。但事情一跑到 View,就會變得相當複雜。很難有一個基礎簡單的思路去整理這些糾結的線條。

所以我最後決定釋出一份這樣的整理指南。這其實也是我們 Rocodev 目前在用的 Rails View 整理技巧。

前情提要

要了解這些用法中間的轉折,首先我必須先解釋幾個前提,這是這些「整理方法」之所以被發明的原因:

  1. 在 View 裡面有 Logic 糾纏 ( if / else & other syntax )是不好的,這會導致 View 很難修改以及維護
  2. 在 View 裡面有 Logic 糾纏是不好的,這會導致 View Performance 下降 ( pure logic )。
  3. 在 View 裡面有 Logic 糾纏是不好的,這會導致 View Performance 嚴重下降 ( with data query )。而這包含在 Helper 裡面 perform data query。

這個 Talk 會包含以下幾個主題:

  • Helper Best Pratices
  • Partial Best Pratices
  • 除了 Helper 與 Partial 之外的整理武器
  • Object-Oriented View
Read on →
 
over 3 years ago

從這次打造 Logdown 的過程中,我還學到寶貴的另外一個經驗:「先做軟體,不要先做平台」。

打造「平台」,幾乎是大多數人對於做網站的第一個預設想法。

如果你跟你的朋友說你要做一個網站,然後說你不是做平台,那麼大概有 99% 的機率他會以為你是瘋子,不然就是超級外行的笨蛋。如果你跟投資人說,我們沒有要做平台。嗯,他可能連見你都懶....XDD

盲點一:「平台」=「賺錢」=「成本很低」

這個道理很簡單:「平台」=「很大」、「大」=「賺錢」。「平台」=「很多人會主動貢獻內容」、「很多人會主動貢獻內容」 = 「成本很低」。所以,如果你一開始就宣告不做平台,「正常人」會把你當「瘋子」。

盲點二:一開始就要作「功能完善」的「平台」,不然之後修改的成本很高

因為從以前到現在,打造一個網站因為架構和技術上的關係。軟體修改的成本一直被認為是很高的,所以絕大多數人的傾向是:「我應該一開始就要企劃完善,否則之後修改的成本很高。」

而網站上線之後,若網站一開始使用成效不佳,大多數的人檢討也會傾向「應該是宣傳不夠的關係」。


網站失敗的例子很多。後面的結局在趨勢部落格上多到不勝枚數。但有幾個共通點幾乎都是一模一樣的。

  1. 平台「大」不一定「賺錢」。「大」但不知道如何「賺錢」、虧得一屁股的到處都是。
  2. 作平台不等於「很多人會主動貢獻免費內容」。事實上一開站就是死城的平台到處都是,而這件事情會嚇到很多第一次的網站經營者,所以他們下意識的直覺就是花錢「請人來生內容」以避免「死城效應」,否則「死城效應」會讓這個網站在第一個月直接就 GG。
  3. 幸運的用錢熬過頭幾個月後,發現使用者和內容成長的速度還是遠低於預期,沒有使用人力或資本介入,直接放著還是會 GG...

.....(後面的事情寫都寫不完...)

但總而言之,「規劃」過的網站上線後多數的問題是這樣的:

(1) 事情不會如想像一樣的發生。而且絕對比你當初預期之外的的最糟狀況還要更糟。
(2) 不知道如何解決「死城效應」,只好用錢續命。
(3) 六個月以後終於發現問題完全不在「宣傳不夠」。而是在於「沒有解決任何問題」、「解決的問題價值不夠付薪水」。
(4) 九個月以後,發現解決根本的問題的手段在於「改版」(因為原先的手段錯了)。但「改版」會遇到的問題在於「舊的功能是否要留著,砍了很可惜」。「新舊版本並存的軟體成本問題」。「開發新版本的金錢成本問題和時間成本問題」。


承認失敗永遠是走出困境的第一步 : 往反方向而行

無疑的這對誰來說都是一個很難解決的困境。勵志書上常說「承認失敗永遠是走出困境的第一步」。我在自己上班的時候,曾經作過很多網站。在做過那麼多網站之後,我認知到,「先作平台」是一條我完全負擔不起的路;上班的時候公司的錢多到花不完了,但是還是避免不了掉入這樣的問題。現在我擁有的只是一個更小的公司,自然更玩不起這樣的作法。

所以我這次實驗方向就是:反方向而行。不要急,只做我做得到的事情,看看什麼事情會發生 ( 原先的公司 Rocodev 主要業務還是接案作軟體開發,內部生個產品還算養的起)。令人驚訝的是,我看到了許多以往我從來沒有想像過的世界。

「第一時間」不作平台,只「解決問題」

雖然打造一個「像樣」的「平台首頁」對我們來說「開發成本」是很低(註)的。而且在產品上線之後,許多朋友就覺得我們有機會打造像 Medium 這樣的寫作平台。一直希望我們加上「社群首頁」、「社群功能」,往平台發展。

但是我們一直有意無意的「拒絕」這麼做,直到最近才終於上了 Explore Logdown 這個功能。

在此之前,我們幾乎把接近 100% 的重心都放在打造 Logdown 的「寫作工具」之上。我們花了非常非常多的心力在打造這個編輯器之上,如果你知道我們在這個 Markdown 編輯器上花的心力、開發的 Editor Hack、和遇到的問題難度,你可能會嚇一大跳...(有空我會請同事簡單介紹我們解決了哪一些在實作編輯器上的 issue ...)

因為我相信一件事:「有解決到的問題的軟體才會有人要用。」

身為平台者開發的我們,往往會有一個巨大盲點:「我開發了一個平台,就會有人主動來用。」但若以使用者的角度來說:「你開發了一個平台,關我屁事,為什麼我要主動用,甚至從此搬到你家。」

我們之所以會把所有的優先權,幾乎全部貫注在後台功能之上。是因為如果連自己都無法愛上我們自己的產品,不覺得不用 Logdown 寫部落格會死,那怎麼有可能讓其他人也喜歡用。

而一旦大家喜歡用這個工具寫文章,自然內容的產生質和量就不是什麼問題了,作平台的門檻也沒有那麼高了。

(目前文章不包含搬家的文章,在 Logdown 上大概每個月文章產生速度大約在 6000 篇以上,系統文章數量目前是 14 萬篇以上...)

只有一件事需要作:「把產品做好」

Logdown 在頭三個月幾乎不作所有「社群平台」有關功能,還有一個沒什麼人知道的好處:不用花時間去分辨使用率低到底是因為宣傳不夠的關係,還是純粹只是因為產品爛...。如果沒人用,就是產品很爛沒有第二句話好說 XD

如果一個產品的問題相對只剩下產品品質,那需要努力的方向也只剩下「把產品做到好」。不用為其他不存在的事情忙的焦頭爛額還一點效益都沒有。

軟體就是必須要一直調整,一直砍掉重練...

在做這個產品時,我們還在心理上先接受了一個事實:作產品就是要一直修改一直修改一直修改,必要時還要砍掉重練。雖然我們是職業軟體開發團隊,但不代表我們就沒有開發成本問題。

修改在往常讓 RD 難以接受的是因為:

(1) 軟體修改成本很高。(有可能因為是當初假設錯誤,或者是程式碼規劃不好)
(2) 你不知道修改之後,效果會比之前的好還是之前的爛。情感上很難接受以前的功能是「作錯了」這件事。或者只是「不覺得別人(通常是 PM)的意見是正確的」。

因為我們的開發是 Complain Driven Development(被不同人抱怨三次以上我們才要作)。Feature 正確率大概有 90% 以上...

當團隊基本上知道自己起碼是按照一個「相對正確」的方向走過去。心理上就不太會抗拒「修改所產生的成本」這件事。

一開始就作「收錢」的產品

許多人會對 Logdown 的「大膽」感到驚訝,為何一個「開發中」的軟體,就打算收錢?這在許多方面看來都是覺得奇怪的:

(1) 你們不是第一個作部落格軟體的。如何有自信讓使用者「好」到「值得付錢」?
(2) 一開始就收錢,不會把使用者「嚇跑」嗎?

我想這沒有絕對的答案。若要談當初的想法,我的觀念純粹是:

(1) 我現在開公司,做的東西理論是就是要收錢的,只是何時才要收?
(2) 我不想按照免費使用者的建議努力去作,做出一個到最後叫好(很多人稱讚)不叫座(根本不賺錢)的東西。
(3) 我不覺得「好」= 「值得付錢」。我認為「有解決問題」= 「值得付錢」。

我想最快知道要如何賺錢的方式,就是用直接一點的手段去作,直接收一個「還可以接受」的價錢,看看會發生什麼事。當然這個手段,現在由結果看算是相當不錯的:

(1) 網路上馬上有人罵,「哇靠,一個 Beta 的東西,沒有 OO 和 XX 還敢收錢,要不要臉」。我馬上就知道原來要收錢,至少要作 OO 和 XX,不用猜老半天...
(2) 朋友密我:「hmmm...但是你們可不可以把哪個 feature 改成這樣那樣,只差這個,我就願意付錢了。」我馬上就知道,哦,原來某些使用者最在意的是什麼功能一定要做到,他們願意付錢就只買這個功能。
(3) 其他公司直接打給我說:「hmmm...你們可不可以作什麼什麼功能,我願意付錢作 Enterprise 客製。」

我們是一個非常小的團隊,根本沒有能力負擔市場調查的成本,但是只公告了我們要收錢,我們馬上就知道要如何賺錢了。而甚至結果也不差,我們第一個月的收到的數字甚至可以打平整個開發團隊的薪水...(原本以為作部落格一定會賠的要死...)

甚至還有更意料不到的事情:使用者說我們的編輯器只用在部落格系統上實在太浪費了,可不可以作什麼什麼系統也用這個編輯器,他們也願意付錢 XDDDD

Summary

當然,這樣做的心臟要非常大顆。因為這樣做的方式,跟「一般作網站」的方式,差異非常非常的大,遭受周遭的人質疑也會非常非的兇,你甚至不可能在一開始拿到任何資源,因為沒有人會相信你這樣會是有結果的。但不可諱言的,這卻是我一直想做的一件事,我一直想看看這樣作,最後究竟會看到怎麼樣的世界。

我在 2011 年寫過一篇文章: 魔球,一個搞清楚產業重點的棒球故事 。這篇文章其實就是當初我創業的動機之一,只是在這篇文章裡面這樣的手段,不管身在哪一個公司,是不可能被任何老闆准許的。所以最後才走上了創業這條路。

Logdown 才剛開始沒幾個月,現在小小的成績實在不能證明什麼。但是,我開始知道原來不走那條相對很遠的路,也是可以的。


廣告:歡迎試用 Logdown,一個很棒的部落格寫作平台,我猜你應該也會喜歡它的。

 
over 3 years ago

Lean Startup 是最近幾年來的顯學,其主要的訴求是創業者應該先把重點放在打造一個 Minimum Viable Product (MVP),觀察市場的需求,再行調整變化商業主軸成長。

這一套理論在近年來被大家一直傳誦,已經讓人聽到長繭了。但是最讓眾人疑惑的其實還是幾點:

(1) 所謂的 Minimum 到底要砍到多少才是 Minimum ?
(2) 這麼少的 Feature 的站台,難道真的會有人來用嗎?
(3) 如何證明一開始少功能的站台真的比多功能的站台好處還要多?
(4) 開發一個產品,初期應該做到多少功能,才算是足夠?

這幾個問題,也是我一路以來一直想知道的答案。

我們團隊最近很紅的產品 Logdown,其實從來不是一個「計畫中」的產品。它只是一個我們眾多一直很想做的點子的其中一個,然後在 Hackathon 中莫名其妙的被做完了原始的 prototype,然後莫名其妙的變成了產品,最後莫名其妙的變成了一間公司。

從這三個月莫名其妙的旅程中,在 Logdown 的茁壯過程,我趁機會執行了一狗票過去幾年來一直我觀察到的現象、卻從來沒有機會在職場上印證的假設,意外的得到了不少答案...

多小的產品規格才是 MVP:"一個"足夠解決問題的功能範圍

在做 Logdown 之前,我自己作過很多產品,也幫客戶作過很多專案。讓我一直抱有疑惑的是:以規格數來算,在規格裡面被規劃幾條是 MVP?如果以一個中型公司「產品企劃」企劃出的專案,通常規格會多達 20-30 項,那麼所謂的 MVP 是不是 10 項?還是 7 項?

而我後來發現,其實嚴格的定義來說,只需要「一項」。市場上需要一個夠好的寫作平台,嚴格來說,是需要一個夠好的網頁文字編輯器,其實作這樣完全就夠了。

當然,我們當時沒有這麼大膽,覺得作這一個平台只需要這個功能。但是我們的時間和精力只夠我們當下只做這一個功能,然後在這個給定的時間內,做到最好。(因為是在一個 Hackathon 中做的..)

在上線以後,我們就發現這個功能就足夠吸引幾百個人對我們的東西有興趣...

這個原始方向「也許」是對的,所以才會有後續的開發維護。

不是減法原則:直接讓用戶告訴我們什麼是最重要的

把一個只有一個功能的原型變成一個產品,後續的最大挑戰是你知道既有市面上類似的產品有哪些功能。但是,一個成熟的部落格平台有 100 項功能,我們到底要先實作哪些功能?

有些人可能會建議,把 100 條功能先整理調列出來,賦予權重,再投票篩出作最重要的 10 個功能?但幸運的是,因為當時我們公司實在是太忙了,沒有美國時間作「整理」這種事。

我們實作的功能順序是:只要這個功能被不同的 user 抱怨超過 3 次(這種基本功能你們竟然沒有??),這個功能才會真的進我們的 issue tracking list,稱之為 Complain Driven Development。

我們得以把最值得投資的功能在很早的階段就都做完,不用花時間在做錯的功能,再陷入到底要砍還是繼續維護的兩難。

當然,上述的這兩個作法,表面上的風險很大,在一般的公司我的老闆絕對不允許我幹這種事,好險這間公司我是老闆(笑)。

產品 V.S 裝置。既然是作產品,就需要包裝。包裝會帶給產品超乎想像的改進作用...

Faria 的老闆 Theo,曾經寫過一篇文章 Building Complete Products vs. Devices,我相當認同他的觀點。

他提到一個「產品」,內容應該具有以下必備:

  • Support
  • Blog & Twitter
  • Demo Video
  • Setup & Getting Started
  • Print Materials
  • Behind the scenes

一直以來,我覺得台灣大部分的網站都是屬於他口中的「Device」,使用者進來一個網站:

  • 開發者把所有能呈現的功能一口氣呈現
  • 找不到自助說明文件
  • 找不到官方交流管道
  • 找不到回報問題的地方

這也是我之前作產品時的毛病。只是在當時,我並沒有意識到這是 "Product" V.S "Device" 的問題。

也一直以為這些事情是 Beta 站的常態:

(1) 試用的朋友在玩過我寫的 prototype,會開口問:「嗯...你這個應該是 XXX 服務吧?我剛花了一陣時間才搞懂這是什麼」
(2) 使用者只有微小建議,但找不到「只做建議」的地方
(3) 使用者只有卡在小地方,但找不到「只想偷偷問」的地方
(4) 使用者不知道這個服務最近上了什麼新功能,找不到官方素材可以幫忙寫文章廣告...

開發者無法第一時間有效傳達這個服務想解決什麼,使用者也沒有順暢的管道可以反應有價值的意見給開發者。但這些問題似乎卻沒有一些有效的方式可以一次解決。

產品包裝的實驗

而這次作 Logdown,在頭兩週快馬加鞭把大多數的重要功能寫完之後,我決定一反常態,把所有功能開發都暫停下來。讓同事們花了整整兩週,接下來只很奢侈的專注在做首頁與 Tour。

我一直想知道為什麼歐美的網站要花那麼多時間作 Landing 頁面以及 Tour 頁面,Fouder 還那麼有空寄信問候每個使用者網站用得爽不爽?我只知道也許作這些事也許可以解決上述遇到的那些問題...

後來的事情發展證明這個早期投資完全是值得的。我們得到了遠超乎預期的效果:

不需要重複的一再介紹自己

Landing 與 Tour 讓我們不需要重複的一再介紹自己(而且是對世界用戶),使用者幾秒內就能決定這是不是他需要的服務。而 由引導式的流程導引陌生的使用者註冊。

重新審視「產品的核心賣點」

而在製作 Landing 和 Tour 的過程中,也逼開發者重新審視「產品的核心賣點」到底是什麼。

  • 寫英文 Tour 真的很累,所以根本不想要作太多雜魚 Feature,以免還要寫介紹...
  • 在截圖時,發現當初 UI 做的不夠精緻,根本不能上相,只好 UI 大調整...
  • 部落格系統的某些核心重要賣點,我們根本還沒實作。只好趕緊調整優先權,趕快做出來,以免沒有內容可以放...

如果不是採 MVP 的成長方式,我們可能連 Tour 都寫不出來,也沒有機會邊做邊「精練」。

重新審視使用流程是不是合理

我們在寫站內的教學時和對照用戶的來信時,也發現使用者操作功能的流程完全不是我們預期的那樣。如果沒有撰寫 Help,我們不會知道我們設計出的操作模式有些其實完全不合理...

寫信,大量的寫信。使用者絕對主動會告訴你許多開發者想像不到的秘密...

最後一件事我學到的就是:寫信,大量的寫信給你的 user。我平常也是很多 SaaS 用戶的使用者,之前我常覺得一些服務的 Founder 很假掰,怎麼有空寄給使用者問候信。難道是生意太冷清絕望了,才問使用者哪裡做得不好?

收到這些信,偶爾我心情很好也是會回幾封,跟他講我覺得哪些功能不合理,為什麼我用完之後還是沒太高意願付錢。

但是我其實從來沒想過要抄這一招。因為我真的不知道寄信給使用者打招呼要幹嘛....(矛盾?)

但是這次不知道哪裡來的好奇心,想說順便在 Logdown 裡面寄信給 user say hello(設定在註冊後三小時後),想看看會發生什麼事。結果竟然打開潘朵拉的盒子....

我竟然遭受到了有生以來最恐怖的客服信 DDoS,在 Logdown 開始寄 hello 的信的第一個月,我收到了幾百封的使用者意見信,回到手真的是差一點都快斷掉了。

這才讓我意識到,不是使用者小氣不肯給開發者意見,他們只是懶得上 support,或覺得事情沒嚴重到值得寫 support。但如果是你「順便」寫信問候他,他會很樂意「順便」「回信」「給你一點意見」。

我們從這些幾百封的信裡面得到了大量的改進意見,許多的點是我們從沒想像到的。而且與我們官方 Support 上的 issue 類型都完全不一樣。

如果是像以前 device 型的作網站。我們不知道會多走多少冤枉路...

Summary

Logdown 是我們團隊作過有史以來「最少」「功能」的一個網站。最少功能並不是指實際上被開發的功能最少,而是經過「正規」「規劃」所做出的功能最少。幾乎都是「被很多使用者要求」「真的有必要」才作。

但是就要到達一個「Product」的標準,雖然一直走在「應該是相對正確的方向」,但實際上真的付出的力量遠超過作那些正規的 "Device" 網站。

所以真的不需要再擔心 Minimum Viable Product,Feature 太 Minimum 的問題,打造 Product 與 Device 是需要耗費完全不同等級的心力的...。

 
over 3 years ago

基本用法

不需要傳參數的狀況

不需要傳參數進 cells

<%= render_cell :statics, :today %>
class StaticsCell < Cell::Rails
  def today
    ....
    render
  end
end
  • 如果不需要參數,那麼就跟一般 ruby method 一樣
注意
  • 如果這個 method 需要 render view ( 90% 的狀況需要),method 最後一定要加 render。很多開發者 debug 到死就是因為不知道要加 render

  • 換句話說,如果沒加 render,其實可以拿來吐 cached 過的 pure result,如 ArrayString...etc.

需要傳參數的狀況

在上一篇文章,我們需要傳一個 user 進去撈資料。那麼 View 是這樣寫的

app/views/users/show.html.erb
   <%= render_cell :user, :rencent_posts, :user => :user %>

如果需要傳多個以上的參數,後面繼續加就可以了。

   <%= render_cell :auction, :daily_data, :user => :user, :date => Date.today %>

在 Cells 裡面收資料,使用第一個 argument 收進來。

class AuctionCell < Cell::Rails
  def daily_data(args)
    @user = args[:user]
    @date = args[:date]
    render
  end
end

打 Cache

在一般的狀況下,使用 Cells 是「沒有 cache」的,也就是普通的 View component 而已。要有 cache 效果必須特別指定...

指定時間

class UserCell < Cell::Rails

 cache :recent_posts, :expires_in => 1.hours

  def recent_posts(args)
    ...
  end
  
end

指定條件 cache

有時候,開發者希望該個元件除了一個小時 Cache 之外,還希望這個物品一旦內容被更新時,不要管一個小時原則,立刻更新。那麼可以用這樣的方式更新。

class ProductCell < Cell::Rails
  cache :product, :expires_in => 1.hours do |cell, item|
    "#{item[:product].id}-#{item[:product].updated_at}"
  end
  
  def info(args)
    @product = args[:product]
    render
  end
end  

使用 Helper

在 cells 時,是無法用 Rails 裡面的 helper 的,所以會出現 method undefined,必須在 cells 手動宣告。

class ProductCell < Cell::Rails

  helper ProductsHelper
 
  def info(args)
    @product = args[:product]
    render
  end
end  

使用 Cells 外的 partial

在 Cells 時,也是無法用 Rails 內的 partial,必須手定指定

class ProductCell < Cell::Rails
  append_view_path("app/views")
 
  def info(args)
    @product = args[:product]
    render
  end
end  

使用 current_user

有時候想偷懶,在 Cells 時直接呼叫 devise 裡面提供的 current_user,而非傳一個 user 參數進來。(我很不建議直接使用 current_user ...)

不過這也是可以做到的。在 Cells 裡面宣告 helper_method 就可以了。

class UserCell < Cell::Rails
  include Devise::Controllers::Helpers
  helper_method :current_user
   
  def recent_posts(args)
    ...
  end
end


這篇就大概 cover 使用 Cells 95% 上會遇到的狀況了。

後面幾個用法是 undocumentd features,解法當初是在 issue list 上或是 source code 撈到的...

小結

雖然現在已經有 Cache Digest 了,但我本身還是偏好使用 cells。理由當然是不外乎 cells 還是可以解決不少封裝的問題,而不只是當作 cachable partial ....

如果你在專案中常遇到 View 有複雜難以整理的問題,我相當推薦使用 cells

另外作者 Nick,在 Twitter 上有帳號 apotonick,歡迎 follow 他。

兩年前 (2011) 他也有來台灣參加過 RubyConf Taiwan,當時是借住在我租的公寓....XD。

系列連結: