說我想在我的控制器中存儲一些變量。我想在一個動作中初始化它,在另一個動作中增加它,並在另一箇中讀取它。只是聲明這個變量@foo
不起作用,因爲@foo
在創建它的操作被呈現後死亡。
我不希望這個變量存儲在模型中。如何在控制器中的多個操作中存儲實例變量?
有沒有辦法保存這個變量,除了將它存儲在會話中?
看起來好像我已經遇到了這個簡單的問題幾次,我想知道解決它的最好方法。
說我想在我的控制器中存儲一些變量。我想在一個動作中初始化它,在另一個動作中增加它,並在另一箇中讀取它。只是聲明這個變量@foo
不起作用,因爲@foo
在創建它的操作被呈現後死亡。
我不希望這個變量存儲在模型中。如何在控制器中的多個操作中存儲實例變量?
有沒有辦法保存這個變量,除了將它存儲在會話中?
看起來好像我已經遇到了這個簡單的問題幾次,我想知道解決它的最好方法。
不是。每個對控制器動作的調用都是無狀態的。控制器操作完成後沒有任何東西可用。爲每個請求創建一個新的控制器實例,然後在請求結束時丟棄該實例。
如果您不想將它存儲在會話或數據庫模型中,如果您希望該變量特定於特定會話,則沒有多個選項。
如果是跨所有會話全局的,你可以把它放在一個@@class_variable
而非@instance_variable
,但是這會導致混亂,一旦你開始有多個Rails進程(每個進程都會有自己的它複印件),或者如果你正在線程安全模式下運行,你可能會遇到討厭的併發錯誤。
我想你可以看看像memcached的,但你仍然需要密鑰的一些USER_ID或其他會話標誌(除非它是全球)
你可以利用內置的Rails.cache機制來存儲值,但正如第一個答案中提到的,您必須將其鍵入user_id之類的值。這是一個不錯的方式,因爲您可以使用不同的存儲機制來備份它。你可以看看
Rails.cache.write(:foo)
# in later action
Rails.cache.read(:foo)
的另一件事是閃光的哈希,它提供了一個保持方法,使最後比一個後續請求更多閃光價值。
所以在行動1,你可以創造的價值:
flash[:foo] = some_value
flash.keep(:foo)
在行動2,你可以訪問它,並調用如果你想活命更多的後續行動再次保持。
flash[:foo] #use it for something
flash.keep(:foo) # keep it for another request
在http請求的上下文中乾淨地執行是件棘手的事情。
如果它是一個簡單的計數或字符串,我認爲最好的解決方案是將它存儲在會話中。這樣,如果您使用多個Web服務器,它將在那裏。
你爲什麼反對使用這個會話?
我也想知道爲什麼你反對使用會議?如果您不喜歡直接在操作中使用會話,則可以使用篩選器模擬存活的@foo
實例變量。這樣的事情可能嗎?
class FooController < ApplicationController
before_filter :load_foo
after_filter :save_foo
private
def load_foo
@foo = session[:foo] || 0
end
def save_foo
session[:foo] = @foo
end
end
你的行動將能夠操縱通過@count
實例變量的值,這將被自動保存到會話。
別擔心,會議不會咬人。
此外,會話可能是這樣做的最佳方式。
緩存是一個好主意,但我認爲如果您有多個Web服務器,則Flash方法將不起作用。 – Scott 2009-07-23 14:19:51
這取決於您的會話存儲,因爲閃存散列實際上存儲在會話中 - 例如,如果會話被禁用,只有flash.now可以運行 – paulthenerd 2009-07-23 17:04:24