情報をThread.current
ハッシュ(たとえば、current_user、現在のサブドメインなど)に保存する方法について、相反する意見が出続けています。この手法は、モデルレイヤー内の以降の処理(クエリのスコープ、監査など)を簡素化する方法として提案されています。
多くの人は、MVCパターンに違反するため、この慣行は受け入れられないと考えています。他の人はアプローチの信頼性/安全性について懸念を表明しており、私の2部構成の質問は後者の側面に焦点を当てています。
Thread.current
ハッシュは、そのサイクル全体を通じて、1つの応答に対してのみ使用可能でプライベートであることが保証されていますか?
応答の最後にあるスレッドが他の着信要求に渡される可能性があり、それによりThread.current
に格納されている情報が漏洩する可能性があることを理解しています。そのようなセキュリティ侵害を防ぐには、応答の終了前にそのような情報をクリアすること(たとえば、コントローラーのThread.current[:user] = nil
からafter_filter
を実行すること)で十分ですか?
ありがとう!ジュゼッペ
スレッドローカル変数を避ける特別な理由はありません。主な問題は次のとおりです。
したがって、使用するのは完全に問題ではありませんが、bestアプローチはそれらを使用することではありませんが、時々、スレッドローカルが最も単純な解決策になる壁にぶつかる非常に多くのコードを変更し、妥協する必要があります。スレッドローカルで完全ではないオブジェクト指向モデルを使用するか、同じことを行うために非常に多くのコードを変更します。
だから、それは主にあなたのケースにとって最善の解決策になるだろうと考えている問題であり、あなたが本当にスレッドローカルパスを下っているなら、私はあなたが後にクリーンアップすることを覚えているブロックでそれを行うことを確かに勧めます次のように行われます。
around_filter :do_with_current_user
def do_with_current_user
Thread.current[:current_user] = self.current_user
begin
yield
ensure
Thread.current[:current_user] = nil
end
end
これにより、このスレッドがリサイクルされる場合、使用される前にスレッドローカル変数がクリーンアップされます。
この小さな宝石は、スレッド/リクエストのローカル変数がリクエスト間で固定されないようにします: https://github.com/steveklabnik/request_store
受け入れられた答えは質問をカバーしますが、Rails 5は「抽象スーパークラス」を提供します ActiveSupport :: CurrentAttributes Thread.currentを使用します。
可能な( 不人気 )解決策として、それへのリンクを提供すると思いました。
https://github.com/Rails/rails/blob/master/activesupport/lib/active_support/current_attributes.rb
受け入れられた回答は技術的に正確ですが、回答で穏やかに指摘されているように、 http://m.onkey.org/thread-safety-for-your-Rails それほど穏やかではありません:
スレッドローカルストレージを使用しない、Thread.current
絶対に必要ない場合
request_store
は別の解決策です(より良い)が、スレッドローカルストレージから離れるより多くの理由のためにそこのreadmeを読んでください。
ほとんどの場合、より良い方法があります。