我遇到了某種範圍問題,它阻止了實例變量被從視圖中調用的助手正確初始化。Ruby on Rails:使用視圖助手初始化實例變量
#sample_controller.rb
class SampleController < ApplicationController
def test
end
end
#application_controller.rb
helper_method :display
def display
if not defined? @display
return @display = "a"
else
return @display += "a"
end
end
#test.html.erb
<%= display %>
<%= display %>
<%= @display %>
<%= @display.reverse %>
當顯示樣本/測試時,它會在「評估nil.reverse」時死亡並顯示錯誤。這是令人驚訝的,因爲前兩個顯示的調用應該已經初始化@display,我會想到的。如果<%= @ display.reverse%>被移除,則輸出爲「a aa」,表示@display實例變量已由輔助方法設置,但在視圖中無法訪問它。
如果控制器修改,從而成爲(與原始視圖代碼):
class SampleController < ApplicationController
def test
display
end
end
輸出成爲「AA AAA一個一個」。如果我讓它在控制器中顯示2個電話,我會得到「aaa aaaa aa aa」。因此,似乎只有在控制器中進行的調用纔會修改SampleController實例變量,而視圖中的調用將修改視圖無法訪問的ApplicationController的實例變量。
這是一個在Rails中的錯誤還是我誤解,這是由於某種原因的預期功能?
我碰到這個bug的上下文是試圖創建一個logged_in? ApplicationController方法,它在第一次調用時設置@user變量,如果用戶登錄,則返回true或false。除非在視圖中使用它之前在控制器中添加了不必要的調用,否則這將不起作用。
因此,在我的真實應用程序中,@display實際上是@user,它用於顯示有關用戶的信息。舉個例子,我的意思是,典型的代碼就像<%if logged_in?%><%= @ user.name%><%end%>。那麼最好的方法是在ApplicationController中設置@user變量來執行before_filter調用?因爲經常,對於給定的視圖,@user的唯一用途就像我上面概述的那樣,並且沒有其他需要在控制器中使用它。 – 2010-01-24 21:48:30
是的,伊娃拷貝機制符合您所描述的內容。在過濾器之前設置@user。 – ffoeg 2010-01-24 21:57:30
謝謝@ffoeg,這個回答非常有幫助。你可以指向任何文檔或導軌指南,這是解釋? View,Controller和Helpers之間共享什麼變量尚不清楚。 – CodeKid 2016-09-17 21:15:48