Arelでjoinしたときにscope(とか検索の条件)を再利用する

会計(Checkout)があって、売られたアイテム(CheckoutItem)をhas_manyしているような状態。

さて、今日の会計の売られたアイテムを調べよう!

今日の会計はこう。

today_range = Date.today ... Date.today + 1
today_checkouts = Checkout.where(:created_at => today_range)

では、今日のアイテムは?

today_items = CheckoutItem.where(:checkout_id => today_checkouts)

と書くか?これだとtoday_checkoutsをいちいちfetchして来ちゃうので、ちょっと微妙*1。じゃあちゃんと条件を書く?

today_items = CheckoutItem.joins(:checkout).where(:checkouts => { :created_at => today_range })

joinした先の条件が複雑になると泣きたくなる。scopeとかでかっこ良く書けてても、ここで書かないといけないのはちょっと……


と思っていたのが、さっきまでの俺。

today_items = CheckoutItem.joins(:checkout).merge(today_checkouts)

解決。

to_sqlしてみると、today_checkoutsがfetchされてないことが確認できる。

*1:to_sqlしてみると、WHERE checkout_id IN (....)になってる