在寫view時,常常會因為過多的邏輯判斷,導致整個view的程式碼非常冗長且難以維護,其實view只是將處理好的資料呈現出來而已,不應該把複雜的邏輯寫在view裡面,此時我們就可以用到helper來解決。
一般在rails裡,view拿不到controller裡的方法,只能拿到對應的action的實體變數,這時候我們就需要用到helper來將方法寫給view使用。
helper的目的是要寫一段ruby code 協助整理資訊,並且可以做兩件事:
簡單來說,只要寫在helper裡的方法,view與comtroller都可以取用。
最近寫專案有寫到購物車,每一個使用者擁有一台車,如果在每次想要撈使用者購物車的資料都要 current_user.cart
的方法去找感覺很麻煩,何不就自己寫個 current_cart
呢?
解決方式有兩個:
#_navbar.html.erb
#加入
<%= link_to "購物車(#{current_cart.items.count})", "#" %>
噴出找不到方法 current_cart
,因為還沒寫嘛!
在寫helper之前,要先注意命名的對應,檔名如果是products_helper.rb,則檔案內的 module 後就得寫 ProductsHelper,跟 controller 的命名對應規則是一樣的。
#app/helpers/products_helper.rb
module ProductsHelper
def current_cart
@cart = @cart || Cart.from_hash(session[:cart123])
end
end
如果有車就用這台車,如果沒車就給他一台名叫 cart123
的車並存在session,此時的 product.html.erb
就可以使用 current_cart
了。
如果也想讓controller用
畢竟剛剛寫的helper是個模組,直接 include 進來就好了。
#products_controller.rb
include ProductsHelper
#products_controller.rb
helper_method :current_cart
#方法寫在這
def current_cart
@cart = @cart || Cart.from_hash(session[:cart123])
end
在controller加入 helper_method :current_cart
就可以使helper擁有這個方法,當然view也可以一起使用了。
但如果將方法寫在controller,只有在特定 controller 可以用,如果要全部的controller都可用的話,可貼在最上層的controller:
#application_controller.rb
helper_method :current_cart
#方法寫在這
def current_cart
@cart = @cart || Cart.from_hash(session[:cart123])
end
這兩種方式都是在讓views拿到controller裡面的方法,至於要選擇哪種方法的判斷標準:
Contorller 用得多就寫在 Contorller,view 用得多就寫在 view。
參考資料:
Layout, Render 與 View Helper
“When you find your path, you must not be afraid. You need to have sufficient courage to make mistakes.”
– Paulo Coelho, Novelist
本文同步發佈於: https://louiswuyj.tw/