LoginSignup
23
24

More than 5 years have passed since last update.

[Rails5] includesの書き方・使い方について(ひとつ、複数)

Posted at

●書きたいこと

N+1問題の解消でよくモデル.includes(〜〜〜)という形を使うけど、
(〜〜〜)部分の書き方がわからず調べたのでメモしておく。

●前提

[Spree::OptionType]
         ↓ ↑
  has_many ↓ ↑ belongs_to
      ↓ ↑
[Spree::ProductOptionType] ←中間テーブル
         ↑ ↓
  has_many ↑ ↓ belongs_to
      ↑ ↓
[Spree::Product]

という関係のときに、
includesを使ってOptionTypeとProductをつなぐ場合を考える。
※つなぐといってもテーブル結合のことではない

●表記の仕方

●その1●
Spree::OptionType.includes(:product)
→OptionTypeとProductがつながる




●その2●
これ、

モデル.includes(A: :B)
モデル.includes(A: [:B, :C])

の形でも表せる。
その場合、AがBをメソッドや関連などで持っていないといけない、つまり、
AのオブジェクトにおいてBの名前を使って何かしらを呼び出せるような形になっていないといけない

例えば上のコードは




Spree::OptionType.includes(product_option_types: :product)




とかける。

●前提に書いたけど、この場合、Aに相当するproduct_option_typesはBに対応するproduct
belongs_toの形で関連づけしており、Spree::ProductOptionType.first.productの形で表せるため
このコードでかける。

★別例
Spree::Product.includes(master: [:default_price, :images])

これはSpree::Productが、master(Spree::Variantオブジェクトの1つ)が持っている
default_priceimagesというメソッド(この場合delegateだが)を持っているので、
このような書き方ができる。

※簡単に説明すると、Spree::ProductはSpree::Variantをvariantsという名前でhas_manyしている。
またSpree::Variantの中ではmasterというscopeがあり、これは
「Spree::Variantのレコードの中でこの条件を満たすものをmasterとします」という旨のscopeである。
default_price, imagesはSpree::Variantの中でdelegateされているので、
Spree::Product.first.variants.first.display_priceという形で使える。
(これだとN+1が発生しますが)




以上、備忘録〜(2記事目)

23
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
24