はい、特徴です。
に渡されたすべての値はwhere
、リレーション ( ) によって内部的に格納され、@values[:where]
AND で結合されて WHERE ステートメントを構築します。
two
によって返されたリレーションのコンテキストで呼び出すとone
、新しいスコープを構築するための基礎として、1 によって格納された「where 値」が使用されます。
以下を使用して、目的の動作を得ることができますunscoped
。
one.unscoped.two
編集: はい、明らかに奇妙で直感に反しています。
私はちょうどあなたと同じ問題に悩まされました。
掘り下げた結果、Rails 4以降、すべてのモデルは、そのクラス/リレーションで使用されている現在のスコープを格納するスレッドローカルレジストリを保持しているようです. 彼らがなぜそれをしたのか正確にはわかりませんが、私の推測では、それはパフォーマンスに関係しています。
ポイントは、すでに一連のスコープをチェーンしており、クラスを参照する別のスコープを呼び出そうとした場合(two
例のように)、ActiveRecord はクラスの現在のスコープ、つまり呼び出した関係をフェッチするだけです。そもそもスコープ!かなりばかげています。実際、クラス参照two
なしでメソッドを書き直すことができますが、何も変更されません。A
奇妙で奇妙なことに、 STI を使用すると別の問題が発生しました。私のスコープでは、 を使用して親モデルにまったく関係のない呼び出しを行いましたpluck
。この「機能」は予期しない方法でクエリに影響を与えただけでなく、デフォルトのスコープも「リセット」しているように見えるため、次のクエリ (スコープの実際の戻り値) は、前のクエリによって渡されたすべての条件を「忘れて」しまいました。スコープ... なんだ?
結論: Rails github でチケットを開き、少なくともチームにこの奇妙な動作を文書化するよう依頼する必要があると思います。(MyClass.unscoped
最初のクエリで使用すると問題は解決しましたが、直感的ではありません)