0

例如,下面的代码:

class FoosController < ApplicationController
  def index
    if !@foo.nil?
      render :locals => {:bar => @foo}
      return
    else 
      @foo = rand 10
      render :locals => {:bar => @foo}
    end
  end
end

如果我localhost:3000/foos多次加载,它会显示不同的值,如果是开发模式也不足为奇,因为每次浏览器请求进入时,Rails 都会重新加载控制器(以及模型和视图)。

但是即使在生产模式下,当所有内容都加载并保留在那里时,@foo' 的值不会在浏览器请求中保留?每次在网络浏览器上重新加载页面时,都会显示一个不同的数字。那么 Rails 每次都会清除所有值吗?如果我们不使用 DBMS,有没有办法跨请求缓存或“记忆”结果?


令人惊讶的是,我只是尝试使用类变量,而在开发模式下,它每次都给出不同的数字。在生产模式下,数字在 Firefox 上保持不变,然后 Chrome 也会一直显示该数字,直到服务器重新启动:

class FoosController < ApplicationController
  @@foo = nil

  def index
    if !@@foo.nil?
      render :locals => {:bar => @@foo}
      return
    else 
      @@foo = rand 10
      render :locals => {:bar => @@foo}
    end
  end
end

为什么类变量可以记忆而实例变量不能?在 Rails 2.x、3.x 和 Ruby 1.8.7 和 1.9.2 中,使用类变量是一种可靠的跨请求“记住事物”的可靠方法吗?

4

3 回答 3

5

这是一种刻意的和期望的行为,每个请求都会实例化一个新的控制器实例,因此一个请求在处理先前请求的剩余部分时不会遇到任何问题。

您可能希望使用sessionflash散列来@foo跨请求存储。

class FoosController < ApplicationController
  def index
    @foo = session[:foo] ||= rand(10)
    render :locals => {:bar => @foo}
  end
end

session[:foo]将一直保持不变,但flash[:foo]如果您只想在一个请求中保持它,则可以使用。

于 2010-10-26T07:46:39.437 回答
2

@@foo指定一个类变量,@foo一个实例变量。每次请求都会创建一个新的控制器实例。对于缓存,我真的推荐 memcache 或类似的东西(由于生产 Rails 服务器的分叉性质)。

于 2010-10-26T07:22:04.437 回答
0

即使您按照 edgerunner 建议的方式进行记忆,在生产中您可能会运行多个 mongrel 或瘦实例,并且这些控制器中的每一个都将具有不同的闪存变量,并且当前的方法将不起作用。继续使用 Tass 所说的诸如 memcache 或 redis 之类的东西,以将这些内容保存在内存中。

于 2010-10-26T09:22:58.937 回答