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の値はブラウザのリクエスト間で維持されませんか? 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

クラス変数はメモ化できるのに、インスタンス変数はメモ化できないのはなぜですか? クラス変数を使用することは、Rails 2.x、3.x、および Ruby 1.8.7 と 1.9.2 で確実にリクエスト全体で「物事を記憶する」ための信頼できる方法ですか?

4

3 に答える 3

5

これは意図的で望ましい動作であり、すべてのリクエストが新しいコントローラーインスタンスをインスタンス化するため、リクエストは以前のリクエストの残りを処理するのに問題はありません。

sessionまたはハッシュを使用して、リクエスト間flashで保存することをお勧めし@fooます。

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

session[:foo]ずっと永続的ですが、flash[:foo]1つのリクエストにわたって永続化したい場合に使用できます。

于 2010-10-26T07:46:39.437 に答える
2

@@fooクラス変数、@fooインスタンス変数を指定します。コントローラの新しいインスタンスは、リクエストごとに作成されます。また、キャッシングについては、memcache などを強くお勧めします (実稼働レール サーバーのフォークの性質のため)。

于 2010-10-26T07:22:04.437 に答える
0

エッジランナーが提案する方法を覚えていても、本番環境では複数の雑種またはシンインスタンスが実行されている可能性があり、それらのコントローラーはそれぞれ異なるフラッシュ変数を持ち、現在のアプローチは機能しません。Tassがmemcacheやredisのようなものを言っていることを先に進めて、そのようなものをメモリに保持します。

于 2010-10-26T09:22:58.937 に答える