🖥

#Rails の preload では関連先テーブルの絞り込みはできず、eager_loadでは可能 ( joins / includes

2023/09/01に公開
# preload では 自分からの検索は可能
users = User.where(id: [1,2,3,4,5]).preload(:books)

# preload では 関連先のテーブルからの検索は不可能
users = User.preload(:books).where(books: { name: "Alice Wonder Land" }).first
# ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column ...


# preload  + joins で関連先のテーブルからの検索が可能だが、 join の作用で 関連先テーブルの数だけ返ってくる結果数も多くなる
# 同じUserのインスタンスが大量に返ってきたり
# merge でも where でも書けるが、どちらでも挙動は変わらないっぽい?
users = User.joins(:books).preload(:books).where(books: { name: "Alice Wonder Land" })
users = User.joins(:books).preload(:books).merge(Book.where(name: "Alice Wonder Land" ))

# preload  + joins 
# uniq すれば User もユニークになるが、なんだか無理やりな気もする
users = User.joins(:books).preload(:books).merge(Book.where(name: "Alice Wonder Land" )).uniq

# eager_load では関連先テーブルからも検索も可能
users = User.eager_load(:books).where(books: { name: "Alice Wonder Land" })


# includes は preload と eager_load のどちらかを自動で切り替えてくれるので、関連先テーブルから検索しようとすると、eager_load と同じクエリ、同じ挙動になる
users = User.includes(:books).where(books: { name: "Alice Wonder Land" })

ヒント

.to_sql メソッドでクエリの中身を見てみたり、そのSQLを直接 DB に発行して、返ってくるDBの結果を見てみよう。

参考

ActiveRecord ~ 複数テーブルにまたがる検索(preload, eager_load, include, joins) - Qiita

Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/3062

チャットメンバー募集

何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ

Twitter

https://twitter.com/YumaInaura

公開日時

2020-04-11

Discussion