これは解決されましたが、私はこれに参加し、この問題をどのように修正したかを報告したかっただけです。OPと同じ症状があり、最初のリクエスト.id()は正常に機能し、後続のリクエスト.id()は「スタックが深すぎます」というエラーメッセージをスローしました。通常、どこかに無限ループがあることを意味するため、これは奇妙なエラーです。私はこれを変更して修正しました:
config.action_controller.perform_caching = true
config.cache_classes = false
に
config.action_controller.perform_caching = true
config.cache_classes = true
環境/ production.rb にあります。
更新: この問題の根本原因は cache_store であることが判明しました。デフォルトの MemoryStore は ActiveRecord モデルを保持しません。これはかなり古いバグであり、かなり深刻です。なぜ修正されていないのかわかりません。とにかく、回避策は別の cache_store を使用することです。config/environments/development.rb でこれを使用してみてください:
config.cache_store = :file_store
更新 #2: C. Bedard がこの問題の分析を投稿しました。うまくまとまりそうです。
私自身、この問題に遭遇した (そして何度も行き詰まった) ため、エラーを調査しました (うまくいけば、適切な修正が見つかりました)。これについて私が知っていることは次のとおりです。 ActiveRecord::Base#reset_subclasses がリクエスト間でディスパッチャーによって呼び出されたときに発生します (開発モードのみ)。
ActiveRecord::Base#reset_subclasses は、inheritable_attributes ハッシュ (#skip_time_zone_conversion_for_attributes が格納されている場所) を消去します。これは、#1290 の「monkey test app」が示すように、リクエストを通じて永続化されたオブジェクトで発生するだけでなく、AR で生成された関連付けメソッドにアクセスしようとしたときにも、現在のリクエストでのみ存在するオブジェクトに対しても発生します。
このバグは、#skip_time_zone_conversion_for_attributes 宣言が base.cattr_accessor から base.class_inheritable_accessor に変更されたこのコミットによって導入されました。しかし、繰り返しになりますが、その同じコミットは別のものも修正しました。ここで最初に提出されたパッチは、reset_subclasses の instance_variables と instance_methods のクリアを単純に回避するだけで、大量のリークを引き起こします。リーク量は、アプリの複雑さ (つまり、それぞれのモデル、関連付け、および属性の数) に正比例するようです。パッチが適用されると、開発モードでの各リクエストで約 1Mb リークするかなり複雑なアプリがあります。したがって、実行可能ではありません(とにかく私にとって)。
これを解決するためのさまざまな方法を試しながら、最初のエラー (2 回目のリクエストで skip_time_zone_conversion_for_attributes が nil である) を修正しましたが、別のエラーが発見されました (最初の例外が発生する前に発生したため、発生しませんでした)。このエラーは、#774 (「id」メソッドの method_missing でのスタック オーバーフロー) で報告されたエラーのようです。
さて、解決策として、私のパッチ (添付) は次のことを行います: #skip_time_zone_conversion_for_attributes メソッドのラッパー メソッドを追加し、値を常に class_inheritable_attribute として読み書きするようにします。このように、 nil はもう返されません。
reset_subclasses が呼び出されたときに「id」メソッドが消去されないようにします。AR は、最初にソースで直接定義しますが、最初に呼び出されたときに #define_read_method で再定義するため、ちょっと奇妙です。そして、それがまさにリロード後に失敗する原因です(reset_subclassesがそれを一掃するため)。
また、reload_models_test.rb にテストを追加しました。このテストは、reset_subclasses を呼び出して、開発モードでのリクエスト間のリロードを試行およびシミュレートします。この時点で私が判断できないのは、ライブ ディスパッチャ リクエスト サイクルで行うように、実際にリロード メカニズムがトリガーされるかどうかです。スクリプト/サーバーからもテストしましたが、エラーはなくなりました。
長い貼り付けで申し訳ありません。Rails lighthouse プロジェクトが非公開であることは残念です。上記のパッチは非公開です。