Rails3 如何寫 Helper 可以傳 Block 參數

Rails3 beta2 開始確定新的 <%= %> 的用法了,像是 form_for, div_for 等要改成 <%= %> 而不是我們習慣已久的 <% %>,主要是因為這樣統一了 <%= %> 就表示內容會輸出的慣例。目前是兩種寫法都可以,只是本來的寫法會有警告訊息 DEPRECATION WARNING: <% %> style block helpers are deprecated. Please use <%= %>,應該到 Rails 3.1 就會正式移除。用法可以參考 ERB Blocks in Rails 3 一文。

而我這篇接下來要示範的是,如果我們想要自己寫一個 helper,可以接受 block 參數要怎麼寫? 例如在 ERB 中,我們希望這樣的程式可以輸出 header blah footer 字串:


# Rails2
<% my_helper do %>
    blah
<% end %>

在 Rails2 的話,如果有包 Block 無論如何都必須用 <% 而不能用 <%=,不然一定會有錯誤訊息。而這個 helper 最常寫成這樣:


# Rails2
def my_helper
  concat("header")
  yield
  concat("footer")
end

或是:


# Rails2
def my_helper(&block)
   tmp = with_output_buffer(&block) 
   concat("header #{tmp} footer")
end

在 Rails2 中,我們得用 concat 表示輸出到 ERB (這算是一個密招,沒人教還真的不會)。但是在 Rails3,則被改成比較直覺的:


# Rails3
<%= my_helper do %>
  blah
<% end %>

以及


# Rails3
def my_helper(&block)
  tmp = with_output_buffer(&block) 
  "header #{tmp} footer"
end

在 Rails3 就不需要用 concat 了,helper 的回傳值透過 <%= 就會輸出在 ERB 上。

Leave a Reply