Rails无法跨浏览器请求缓存预先计算的值?(比如记住n个阶乘结果)

nop*_*ole 0 ruby ruby-on-rails memoization ruby-on-rails-3

例如,以下代码:

class FoosController < ApplicationController
  def index
    if !@foo.nil?
      render :locals => {:bar => @foo}
      return
    else 
      @foo = rand 10
      render :locals => {:bar => @foo}
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

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

但即使在生产模式下,当所有内容都被加载并停留在那里时,@foo浏览器请求的价值也不会停留?每次在Web浏览器上重新加载页面时,都会显示不同的编号.那么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
Run Code Online (Sandbox Code Playgroud)

为什么类变量memoize但实例变量不能?在Rails 2.x,3.x和Ruby 1.8.7和1.9.2中使用类变量是否可靠地在请求中"记住事物"?

edg*_*ner 5

这是一种有意和期望的行为,每个请求都实例化一个新的控制器实例,因此请求在处理先前请求的剩余时没有任何问题.

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

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

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