如何在控制器中的多个操作中存储实例变量?

假设我想在我的控制器中存储一些变量。我想在一个动作中初始化它,在另一个动作中增加它,并在另一个中读取它。用@foo声明这个变量不起作用,因为@foo在创建它的操作完成后死亡。
我不希望这个变量存储在模型中。 有没有办法保存这个变量,除了将它存储在会话中?
似乎我已经遇到了这个简单的问题几次,我想知道解决它的最好方法。

已邀请:

datque

赞同来自:

不是真的。每个对控制器动作的调用都是无状态的。控制器操作完成后没有任何东西可用。为每个请求创建一个新的控制器实例,然后在请求结束时丢弃该实例。 如果您不想将它存储在会话或数据库模型中,如果您希望该变量针对特定会话,则没有多少选项。 如果它在所有会话中都是全局的,那么可以将它放在@@class_variable而不是@instance_variable中,但是一旦开始有多个Rails进程(每个进程都有自己的副本)或者如果您正在运行在线程安全模式下,您可能会遇到令人讨厌的并发错误。 我想你可以看看类似memcached的东西,但是你仍然需要将它键入某个user_id或其他会话标记(除非它是全局的)

ksed

赞同来自:

您可以使用内置的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请求的上下文中干净地执行有点棘手。

id_cum

赞同来自:

如果它是简单的计数或字符串,我认为最好的解决方案是将它存储在会话中。这样,如果您使用多个Web服务器,它将在那里。 你为什么反对使用这个会话?

funde

赞同来自:

我也想知道为什么你反对使用会话?如果您不喜欢直接在您的操作中使用会话,则可以使用筛选器模拟存活的@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实例变量处理该值,并且该值将自动保留到会话中。

funde

赞同来自:

别担心,会议不会咬人。 此外,会议可能是这样做的最好方法。

要回复问题请先登录注册