2008-10-26 89 views
26

我有一個相當舊的模板系統寫在ERB之上。它依賴於存儲在數據庫中的ERB模板。那些被閱讀和渲染。當我想將數據從一個模板傳遞到另一個模板時,我使用:locals參數來Rails渲染方法。爲了在一些模板中設置這些變量的默認變量,我使用了定義的?方法簡單地告訴我,如果局部變量定義;如果沒有使用默認值初始化它是這樣的:定義?方法在Ruby和Rails

unless defined?(perex) 
    perex = true 
end 

我升級應用最新的Rails,我看到一些奇怪的行爲。基本上這有時會起作用(有時perex是未定義的),有時它不會(perex被定義並設置爲零)。這發生在沒有其他變化的情況下

我有兩個問題: 除了使用定義之外,還有其他更好的方法嗎?這證明是不可靠的(在頂級Rails 1.6上可靠幾年)?這樣的方式不應該導致我重寫所有的模板。 我一直在瀏覽Ruby文檔,無法找到關於定義的任何內容?方法。它已被棄用,還是我只是盲目的?

編輯:實際問題是由似乎是Ruby/eRB錯誤引起的。有時除非聲明會起作用,但有時不會。奇怪的是,即使第二條線執行perex斯蒂爾留在世界其他地方。刪除已定義的?解決了。

回答

36

第一個:實際上,defined? is an operator

二:如果我正確地理解你的問題,要做到這一點是與此紅寶石成語:

perex ||= true 

,如果它是未定義或nil那將分配真實perex。這並不完全代表你的例子,因爲當值爲nil時,你不會評估任務,但如果你依賴那個,那麼在我看來,如果沒有看到它,那麼你並沒有寫出清晰的代碼。

編輯:正如Honza指出的那樣,上述聲明將取代perex的值,即false。然後,我提出以下改寫的最小行數:

perex ||= perex.nil? # Assign true only when perex is undefined or nil 
+10

這是不正確的。 perex || = true與perex = perex ||相同如果它是未定義的,則將perex設置爲true,否則爲false。最後的情況會打破一切。 – Honza 2008-10-27 08:16:14

24

測試的最安全的方式,如果在Rails模板定義的本地是:

local_assigns[:perex] 

這是Rails API中記錄以及由於實施限制而無法使用defined?的解釋。

+1

如果perex的價值爲假,該怎麼辦? – 2013-02-08 01:13:38

+0

你可以自己檢查:) perex = true如果local_assigns [:perex] .nil? – Hannes 2013-06-03 16:12:57

12

Per mislav的回答是,我在Rails API中尋找該文檔,並在Class ActionView::Base(標題爲「將局部變量傳遞給子模板」標題下)中找到該文檔。然而,這並不值得搜索,因爲它幾乎沒有比mislav更多的話。但它建議使用此模式:

if local_assigns.has_key? :perex 
6

考慮到considerationg mislav's original answerKenB's elaboration,我認爲以下是絕對的最佳方法(雖然我開到的意見)。如果密鑰不存在於原始散列中,它將利用Ruby的Hash#fetch方法備用替代值。

perex = local_assigns.fetch(:perex, true) 

這比||=方法,大多數用戶會建議,因爲有時你會希望允許false值甚至更好。例如,下面的代碼將從未允許false值在傳遞:

perex = local_assigns[:perex] || true 
相關問題