select
Enumerable の Ruby メソッドです。初めて走る時
user.posts.select{|post| post.topic == "x" }
の関連付けのすべてのPost
インスタンスがデータベースからメモリにロードされます。具体的には ActiveRecord コレクション オブジェクトに。次に、このコレクションに対して が呼び出され、以外の属性を持つコレクション内のすべてのインスタンスが除外されます。user
:posts
select
Post
:topic
"x"
上記の行を 2 回実行しても、データベースは再度クエリされません。これは、既にposts
メモリに読み込まれているためです。
以下のincludes
ようにすると
user= User.includes(:posts).find(1)
:posts
返された各User
インスタンス (この場合、単一のUser
where :id
is )のリレーションを熱心にロードします1
。Post
上記の前のセクションで説明したように、すべてのインスタンスがメモリにロードされました。
その後、次のようなことをすると
user.posts.where(:topic => "x")
に対して新しいクエリを実行するように Rails に指示していますPost
。今回は、 の where と where が のすべてのインスタンスを検索しPost
ます。インメモリ ARel コレクションの「フィルター」のようには機能しません。:topic
"x"
:user_id
:id
user
where
- 悪い別のクエリを避けたい場合
select
は、メモリ内の結果セットをフィルタリングする良い方法です。
- ベンチマークを実行して、どちらが速いかを見つけることができます。
- データベースにクエリを実行し、別の ARel コレクションをメモリに再設定する
- メモリ内の enumberable を反復処理し、Ruby でフィルターを実行する
に関連するすべてが必要ない場合は、これを元のクエリに簡単に含めることができます:posts
user
user.includes(:posts).where("posts.topic = ?", 'x')