Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

●書きたいこと

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記事目)

eitches
Harrifax
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away