使用 SimpleDelegator 裝飾模型
大多數 Rails 開發人員首先在模板中修改他們的模型資訊:
<h1><%= "#{ @user.first_name } #{ @user.last_name }" %></h1>
<h3>joined: <%= @user.created_at.in_time_zone(current_user.timezone).strftime("%A, %d %b %Y %l:%M %p") %></h3>
對於具有大量資料的模型,這可能很快變得麻煩並導致從一個模板到另一個模板的複製貼上邏輯。
此示例使用 stdlib 中的 SimpleDelegator
。
預設情況下,對 SimpleDelegator
物件的所有請求都將傳遞給父物件。你可以使用表示邏輯覆蓋任何方法,也可以新增特定於此檢視的新方法。
SimpleDelegator
提供了兩種方法:__setobj__
用於設定要委託的物件,__getobj__
用於獲取該物件。
class UserDecorator < SimpleDelegator
attr_reader :view
def initialize(user, view)
__setobj__ @user
@view = view
end
# new methods can call methods on the parent implicitly
def full_name
"#{ first_name } #{ last_name }"
end
# however, if you're overriding an existing method you need
# to use __getobj__
def created_at
Time.use_zone(view.current_user.timezone) do
__getobj__.created_at.strftime("%A, %d %b %Y %l:%M %p")
end
end
end
一些裝飾器依靠魔術來連線這種行為,但是你可以通過初始化頁面上的物件使表達邏輯的來源變得更加明顯。
<% user = UserDecorator.new(@user, self) %>
<h1><%= user.full_name %></h1>
<h3>joined: <%= user.created_at %></h3>
通過將對檢視物件的引用傳遞給裝飾器,我們仍然可以在構建表示邏輯時訪問所有其餘檢視助手,而無需包含它。
現在,檢視模板只關注將資料插入頁面,而且更加清晰。