ActiveRecord Rails3スコープとクラスメソッド
-
29-10-2019 - |
質問
ActiveRecordの新しいクエリインターフェイスは初めてなので、まだ理解していません。
ActiveRecordモデルでscope
を使用することと、クラスメソッド(つまり、self.some_method
)を使用することの違いを誰かが説明できることを望んでいました
私が収集できることから、スコープは常にリレーションを返すことが期待されますが、クラスメソッドは必ずしもそうする必要はありません。これは本当ですか?
たとえば、次のようなことをするのは理にかなっていると思いました: ジェネラコディセタグプレ
しかし、これは機能しません。このエラーが発生します: ジェネラコディセタグプレ
ただし、クラスメソッドとしては機能します ジェネラコディセタグプレ
スコープをいつ使用するか、クラスメソッドをいつ使用するかについての人々の考えを知りたいです。スコープは常にリレーションを返す必要があるが、クラスメソッドは必要なものを返すことができると仮定するのは正しいですか?
解決
Rails 2.xには、named_scopesがクエリを実行しなかったため(チェーンできるように)、クラスメソッドがクエリを実行したため(チェーンできなかったため)、手動で行わない限り、より多くの違いがありました。クエリをscoped(...)
呼び出しでラップしました。
Rails 3では、実際の結果が必要になるまですべてがActiveRecord::Relation
を返すため、スコープをクラスメソッドに対してチェーンでき、その逆も可能です(クラスメソッドがActiveRecord::Relation
オブジェクトを返し、他のオブジェクトタイプ(カウントなど)を返さない限り)。
一般的に、私は単純なワンライナーのscope
エントリを使用して、結果セットをフィルタリングします。ただし、詳細なロジック、ラムダ、複数行などを必要とする可能性のある「スコープ」で複雑なことを行う場合は、クラスメソッドを使用することをお勧めします。そして、あなたが捕まえたように、カウントなどを返す必要がある場合は、クラスメソッドを使用します。
他のヒント
Dylan が彼の回答でほのめかしているように、スコープとクラスメソッドの違いの1つは、スコープが評価されるときにクラスがロードされます。これにより、予期しない結果が生じる可能性があります。
たとえば、 ジェネラコディセタグプレ
はエラーが発生しやすいです。正しい方法はラムダを使用することです ジェネラコディセタグプレ
ラムダブロックは遅延評価されます。したがって、Date.todayは、スコープを呼び出すときに実行されます。 クラスが評価されるとき。
クラスメソッドを使用する場合は、ラムダを使用する必要はありません。 ジェネラコディセタグプレ
クラスメソッドを使用するため、コードはメソッド呼び出し時に実行されます。