正如您已經知道所需方法的簽名,最好定義它們而不是使用method_missing
。你可以那樣做(你類定義):
[:bill_date, :registration_date, :some_other_date].each do |attr|
define_method("#{attr}_human") do
(send(attr) || Date.today).strftime('%b %d, %Y')
end
define_method("#{attr}_human=") do |date_string|
self.send "#{attr}=", Date.strptime(date_string, '%b %d, %Y')
end
end
如果列出所有日期的屬性是沒有問題的這種做法是更好,因爲你面對的常規方法,而不是內部method_missing
一些魔術。
如果要適用於該有_date
結尾的名稱的所有屬性,你可以檢索它們像(你的類定義):
column_names.grep(/_date$/)
而這裏的method_missing
溶液(沒有測試過,雖然以前一個也不會被測試):
def method_missing(method_name, *args, &block)
# delegate to superclass if you're not handling that method_name
return super unless /^(.*)_date(=?)/ =~ method_name
# after match we have attribute name in $1 captured group and '' or '=' in $2
if $2.blank?
(send($1) || Date.today).strftime('%b %d, %Y')
else
self.send "#{$1}=", Date.strptime(args[0], '%b %d, %Y')
end
end
此外,它是很好的覆蓋respond_to?
方法和方法名返回true
,你處理內部method_missing
(在1.9中,你應該改寫respond_to_missing?
)。
'method_missing'是你應該採取的最後一根稻草。實際上,定義方法更清晰,導致更好的代碼設計和明確的問題分離,更容易理解,也更快捷。所以如果你可以定義你的方法,你應該總是這樣做。 – 2012-01-16 20:43:04
從KL-7獲知有更好的方法比method_missing更好,但考慮到我有4個不同的日期屬性爲這個模型,手動定義每個不是解決方案。 DRY – tybro0103 2012-01-16 20:57:22
那麼,KL-7的方法實際上是這裏的首選方法。因爲他提出了我的意思:定義方法。 – 2012-01-16 21:18:22