end SELECT "plays".* FROM "plays" LIMIT 10 SELECT "play_actors".* FROM "play_actors" WHERE "play_actors"."play_id" IN (1, 2, 3, ...) SELECT "actors".* FROM "actors" WHERE "actors"."id" IN (1, 2, 3, ...) 3 ͭʹ͚ΒΕͨΫΤϦ͕ൃߦ͞ΕΔ
end SELECT DISTINCT "plays"."id" FROM "plays" LEFT OUTER JOIN "play_actors" ON "play_actors"."play_id" = "plays"."id" LEFT OUTER JOIN "actors" ON "actors"."id" = "play_actors"."actor_id" LIMIT 10 SELECT "plays"."id" AS t0_r0, ... FROM "plays" LEFT OUTER JOIN "play_actors" ON "play_actors"."play_id" = "plays"."id" LEFT OUTER JOIN "actors" ON "actors"."id" = "play_actors"."actor_id" WHERE "plays"."id" IN (1, 2, 3, ...) LEFT OUTER JOIN ͨ͠ ΫΤϦ͕ൃߦ͞ΕΔ
loaded to prevent N + 1 queries. A separate query is performed for each association, unless a join is required by conditions. N + 1 ΫΤϦΛ͙ͨΊʹ args associations Λ eager_load ͢ΔΑ͏ࢦఆ͠·͢ɻ ݅ʹΑͬͯ join ͕ඞཁͰͳ͚Εɺ ֤ association ͝ͱʹݸผͷΫΤϦ͕࣮ߦ͞Ε·͢ɻ
= Play.all end end <% @plays.includes(:actors).each do |play| %> <% play.actors.each do |actor| %> <%= actor.name %> <% end %> <% end %> ɹϏϡʔͰ ɹincludes ͨ͘͠ͳ͍ 🙅
= Play.all.includes(:actors) end end <% @plays.each do |play| %> <% play.actors.each do |actor| %> <%= actor.name %> <% end %> <% end %> ɹίϯτϩʔϥͰ ɹincludes ͍ͨ͠ 🙆
= Play.all.includes(:actors).map do |play| { title: play.name, actors: play.actors.map(&:name) } end render json: { data: plays } end end ɹίϯτϩʔϥͰ ɹ͢ͱΑͦ͞͏ 🙆
json: { data: scope.as_json } end def show render json: { data: scope.find(params[:id]).as_json } end private def scope Play.where('name like ?', params[:name]) end end ɹڞ௨ͷείʔϓΛ ɹ͍ͬͯΔ߹
json: { data: scope.as_json } end def show render json: { data: scope.find(params[:id]).as_json } end private def scope Play.where('name like ?', params[:name]) end end ɹΞΫγϣϯͰ ɹ͖͢…ʁ🤔 ɹ͜ͷ͘Β͍ͳΒ ɹείʔϓͰͯ͠ ɹΑͦ͞͏͚ͩͲ…🤔 ɹshow Ͱ includes ͢Δ ɹඞཁͳ͘ͳ͍ʁ🤔
͕ൃੜ͢Δέʔε class PlaysController < ApplicationController def index plays = Play.all render json: { data: plays.map(&:as_json_with_actors) } end end class Play < ApplicationRecord def as_json_with_actors as_json.merge(actors: actors.map(&:name)) end end
= Play.all.includes(:actors) render json: { data: plays.map(&:as_json_with_actors) } end end class Play < ApplicationRecord def as_json_with_actors as_json.merge(actors: actors.map(&:name)) end end ɹίϯτϩʔϥͰ ɹ͢ͱΑͦ͞͏ 🙆
do |actor| %> <%= actor.name %> <% end %> <% end %> class PlaysController < ApplicationController def index @plays = Play.all end end ɹBullet ͷϩά 2023-10-23 07:21:04[WARN] user: makicamel GET /plays USE eager loading detected Play => [:actors] Add to your query: .includes([:actors]) Call stack /Users/makicamel/awesome_app/app/views/plays/ index.html.erb:2:in `block in _app_views_plays _index_html_erb__3206924200111145907_11500' /Users/makicamel/awesome_app/app/views/plays/ index.html.erb:1:in `_app_views_plays _index_html_erb__3206924200111145907_11500’
do |actor| %> <%= actor.name %> <% end %> <% end %> class PlaysController < ApplicationController def index @plays = Play.all end end 2023-10-23 07:21:04[WARN] user: makicamel GET /plays USE eager loading detected Play => [:actors] Add to your query: .includes([:actors]) Call stack /Users/makicamel/awesome_app/app/views/plays/ index.html.erb:2:in `block in _app_views_plays _index_html_erb__3206924200111145907_11500' /Users/makicamel/awesome_app/app/views/plays/ index.html.erb:1:in `_app_views_plays _index_html_erb__3206924200111145907_11500’ ɹελοΫτϨʔεʹ ɹίϯτϩʔϥ͕ͳ͍
do |actor| %> <%= actor.name %> <% end %> <% end %> class PlaysController < ApplicationController def index @plays = Play.all end end 2023-10-23 07:21:04[WARN] user: makicamel GET /plays USE eager loading detected Play => [:actors] Add to your query: .includes([:actors]) Call stack /Users/makicamel/awesome_app/app/views/plays/ index.html.erb:2:in `block in _app_views_plays _index_html_erb__3206924200111145907_11500' /Users/makicamel/awesome_app/app/views/plays/ index.html.erb:1:in `_app_views_plays _index_html_erb__3206924200111145907_11500’ ɹमਖ਼͍ͨ͠ϑΝΠϧ ɹͬͪ͜ ɹελοΫτϨʔεʹ ɹίϯτϩʔϥ͕ͳ͍
do |actor| %> <%= actor.name %> <% end %> <% end %> class PlaysController < ApplicationController def index @plays = Play.all end end 2023-10-23 07:21:04[WARN] user: makicamel GET /plays USE eager loading detected Play => [:actors] Add to your query: .includes([:actors]) Call stack /Users/makicamel/awesome_app/app/views/plays/ index.html.erb:2:in `block in _app_views_plays _index_html_erb__3206924200111145907_11500' /Users/makicamel/awesome_app/app/views/plays/ index.html.erb:1:in `_app_views_plays _index_html_erb__3206924200111145907_11500’ ɹϏϡʔͰ N+1 Λൃੜͤ͞Δ ɹଟ͘ͷ߹Πϯελϯεมʹೖ͍ͬͯΔ
do |actor| %> <%= actor.name %> <% end %> <% end %> class PlaysController < ApplicationController def index @plays = Play.all end end 2023-10-23 07:21:04[WARN] user: makicamel GET /plays USE eager loading detected Play => [:actors] Add to your query: .includes([:actors]) Call stack /Users/makicamel/awesome_app/app/views/plays/ index.html.erb:2:in `block in _app_views_plays _index_html_erb__3206924200111145907_11500' /Users/makicamel/awesome_app/app/views/plays/ index.html.erb:1:in `_app_views_plays _index_html_erb__3206924200111145907_11500’ ɹN+1 ൃੜߦΘ͔Δ
do |actor| %> <%= actor.name %> <% end %> <% end %> class PlaysController < ApplicationController def index @plays = Play.all end end 2023-10-23 07:21:04[WARN] user: makicamel GET /plays USE eager loading detected Play => [:actors] Add to your query: .includes([:actors]) Call stack /Users/makicamel/awesome_app/app/views/plays/ index.html.erb:2:in `block in _app_views_plays _index_html_erb__3206924200111145907_11500' /Users/makicamel/awesome_app/app/views/plays/ index.html.erb:1:in `_app_views_plays _index_html_erb__3206924200111145907_11500’ ɹରͬΆ͍ ɹΠϯελϯεม͕Θ͔Δʢצʣ
do |actor| %> <%= actor.name %> <% end %> <% end %> class PlaysController < ApplicationController def index @plays = Play.all end end 2023-10-23 07:21:04[WARN] user: makicamel GET /plays USE eager loading detected Play => [:actors] Add to your query: .includes([:actors]) Call stack /Users/makicamel/awesome_app/app/views/plays/ index.html.erb:2:in `block in _app_views_plays _index_html_erb__3206924200111145907_11500' /Users/makicamel/awesome_app/app/views/plays/ index.html.erb:1:in `_app_views_plays _index_html_erb__3206924200111145907_11500’ ɹURL ͕Θ͔Δ
do |actor| %> <%= actor.name %> <% end %> <% end %> class PlaysController < ApplicationController def index @plays = Play.all end end 2023-10-23 07:21:04[WARN] user: makicamel GET /plays USE eager loading detected Play => [:actors] Add to your query: .includes([:actors]) Call stack /Users/makicamel/awesome_app/app/views/plays/ index.html.erb:2:in `block in _app_views_plays _index_html_erb__3206924200111145907_11500' /Users/makicamel/awesome_app/app/views/plays/ index.html.erb:1:in `_app_views_plays _index_html_erb__3206924200111145907_11500’ ɹίϯτϩʔϥͱ ɹΞΫγϣϯ͕Θ͔Δ
do |actor| %> <%= actor.name %> <% end %> <% end %> class PlaysController < ApplicationController def index @plays = Play.all end end 2023-10-23 07:21:04[WARN] user: makicamel GET /plays USE eager loading detected Play => [:actors] Add to your query: .includes([:actors]) Call stack /Users/makicamel/awesome_app/app/views/plays/ index.html.erb:2:in `block in _app_views_plays _index_html_erb__3206924200111145907_11500' /Users/makicamel/awesome_app/app/views/plays/ index.html.erb:1:in `_app_views_plays _index_html_erb__3206924200111145907_11500’ ɹΠϯελϯεมʹ ɹೖ͢Δͱ͜Ζʹ
do |actor| %> <%= actor.name %> <% end %> <% end %> class PlaysController < ApplicationController def index @plays = Play.all.includes(:actors) end end 2023-10-23 07:21:04[WARN] user: makicamel GET /plays USE eager loading detected Play => [:actors] Add to your query: .includes([:actors]) Call stack /Users/makicamel/awesome_app/app/views/plays/ index.html.erb:2:in `block in _app_views_plays _index_html_erb__3206924200111145907_11500' /Users/makicamel/awesome_app/app/views/plays/ index.html.erb:1:in `_app_views_plays _index_html_erb__3206924200111145907_11500’ ɹincludes Λ͢✌
scope if params[:future] @plays = @plays.where(performed_at: Date.today..) end gon.as_json = @plays.as_json end def show @play = scope.find(params[:id]) end private def scope Actor.find(params[:actor_id]).plays end end ɹ͜͜Ͱ includes ͢Δͱ ɹΑͦ͞͏
scope if params[:future] @plays = @plays.where(performed_at: Date.today..) end gon.as_json = @plays.as_json end def show @play = scope.find(params[:id]) end private def scope Actor.find(params[:actor_id]).plays end end ɹͻͱͭͷϝιουͰ ɹෳճೖ͞Ε͍ͯΔ߹ ɹͲͪΒ͕ਖ਼͍͔͠ ɹػձతͳఆແཧ
scope if params[:future] @plays = @plays.where(performed_at: Date.today..) end gon.as_json = @plays.as_json end def show @play = scope.find(params[:id]) end private def scope Actor.find(params[:actor_id]).plays end end ɹ࠷ॳʹೖ͢Δ΄͏͕ ɹϢʔεέʔεͱͯ͠ଟͦ͏
eager loading detected Play => [:actors] Add to your query: .includes([:actors]) Call stack /Users/makicamel/awesome_app/app/views/plays/index.html.erb:2:in `block in _app_views_plays_index_html_erb__3206924200111145907_11500' /Users/makicamel/awesome_app/app/views/plays/index.html.erb:1:in `_app_views_plays_index_html_erb__3206924200111145907_11500' class PlaysController < ApplicationController def index @plays = Play.all end end ɹجຊέʔε
detected Play => [:actors] Add to your query: .includes([:actors]) Call stack /Users/makicamel/awesome_app/app/views/plays/index.html.erb:2:in `block in _app_views_plays_index_html_erb__3206924200111145907_11500' /Users/makicamel/awesome_app/app/views/plays/index.html.erb:1:in `_app_views_plays_index_html_erb__3206924200111145907_11500' class PlaysController < ApplicationController def index @plays = Play.all.includes(:actors) end end Case 1. ɹجຊέʔε
= Play.all end end ɹassociations ͕ ɹෳ͋Δέʔε 2023-10-23 07:21:04[WARN] user: makicamel GET /plays USE eager loading detected Play => [:actors] Add to your query: .includes([:actors]) 2023-10-23 07:21:04[WARN] user: makicamel GET /plays USE eager loading detected Play => [:theaters] Add to your query: .includes([:theaters])
:theaters]) end end Case 2. ɹassociations ͕ ɹෳ͋Δέʔε 2023-10-23 07:21:04[WARN] user: makicamel GET /plays USE eager loading detected Play => [:actors] Add to your query: .includes([:actors]) 2023-10-23 07:21:04[WARN] user: makicamel GET /plays USE eager loading detected Play => [:theaters] Add to your query: .includes([:theaters])
eager loading detected Play => [{:actors=>[:company]}] Add to your query: .includes([:"{:actors=>[:company]}"]) Call stack /Users/makicamel/awesome_app/app/views/plays/index.html.erb:2:in `block in _app_views_plays_index_html_erb__1665884924136242781_11760' /Users/makicamel/awesome_app/app/views/plays/index.html.erb:1:in `_app_plays_index_html_erb__1665884924136242781_11760' class PlaysController < ApplicationController def index @plays = Play.all end end ɹωετ͍ͯ͠Δέʔε
eager loading detected Play => [{:actors=>[:company]}] Add to your query: .includes([:"{:actors=>[:company]}"]) Call stack /Users/makicamel/awesome_app/app/views/plays/index.html.erb:2:in `block in _app_views_plays_index_html_erb__1665884924136242781_11760' /Users/makicamel/awesome_app/app/views/plays/index.html.erb:1:in `_app_plays_index_html_erb__1665884924136242781_11760' class PlaysController < ApplicationController def index @plays = Play.all.includes([{:actors=>[:company]}]) end end ɹωετ͍ͯ͠Δέʔε
USE eager loading detected Play => [:awesome_actors] Add to your query: .includes([:awesome_actors]) Call stack /Users/makicamel/awesome_app/app/views/plays/index.html.erb:2:in `block in _app_views_plays_html_erb___4265071383862059390_11760’ /Users/makicamel/awesome_app/app/views/plays/index.html.erb:1:in `_app_views_plays_index_html_erb___4265071383862059390_11760' class PlaysController < ApplicationController def index @plays = Play.all end end ɹωετ͍ͯ͠Δ͔ͭ ɹassociation ʹผ໊͕͋Δέʔε class Play < ApplicationRecord has_many :play_actors has_many :awesome_actors, through: :play_actors, source: :actor end
Play.all.includes({:awesome_actors=>[:company]}) end end Case 4. 2023-10-26 14:57:19[WARN] user: makicamel GET /plays USE eager loading detected Play => [:awesome_actors] Add to your query: .includes([:awesome_actors]) Call stack /Users/makicamel/awesome_app/app/views/plays/index.html.erb:2:in `block in _app_views_plays_html_erb___4265071383862059390_11760’ /Users/makicamel/awesome_app/app/views/plays/index.html.erb:1:in `_app_views_plays_index_html_erb___4265071383862059390_11760' ɹωετ͍ͯ͠Δ͔ͭ ɹassociation ʹผ໊͕͋Δέʔε class Play < ApplicationRecord has_many :play_actors has_many :awesome_actors, through: :play_actors, source: :actor end
USE eager loading detected Actor => [:company] Add to your query: .includes([:company]) Call stack /Users/makicamel/awesome_app/app/views/plays/index.html.erb:3:in `block (2 levels) in _app_views_plays_index_html_erb__2119670124553133993_11760' /Users/makicamel/awesome_app/app/views/plays/index.html.erb:2:in `block in _app_views_plays_index_html_erb__2119670124553133993_11760' /Users/makicamel/awesome_app/app/views/plays/index.html.erb:1:in `_app_views_plays_index_html_erb__2119670124553133993_11760' class PlaysController < ApplicationController def index @plays = Play.includes(:actors) end end ɹҰ෦ includes ࡁͷέʔε
USE eager loading detected Actor => [:company] Add to your query: .includes([:company]) Call stack /Users/makicamel/awesome_app/app/views/plays/index.html.erb:3:in `block (2 levels) in _app_views_plays_index_html_erb__2119670124553133993_11760' /Users/makicamel/awesome_app/app/views/plays/index.html.erb:2:in `block in _app_views_plays_index_html_erb__2119670124553133993_11760' /Users/makicamel/awesome_app/app/views/plays/index.html.erb:1:in `_app_views_plays_index_html_erb__2119670124553133993_11760' class PlaysController < ApplicationController def index @plays = Play.includes(:actors).includes({:actors=>[:company]}) end end ɹҰ෦ includes ࡁͷέʔε
marker.skip? if associations[marker.index] associations[marker.index].add(marker) else associations[marker.index] = Associations.new( marker, @application_associations, @loaded_associations ) end end end end ɹBullet ͷܯࠂΛநԽͨ͠ ɹΠϯελϯε
marker.skip? if associations[marker.index] associations[marker.index].add(marker) else associations[marker.index] = Associations.new( marker, @application_associations, @loaded_associations ) end end end end ɹN+1 ൃੜՕॴΛΩʔʹͯ͠ ɹ ɹ
marker.skip? if associations[marker.index] associations[marker.index].add(marker) else associations[marker.index] = Associations.new( marker, @application_associations, @loaded_associations ) end end end end ɹN+1 ൃੜՕॴΛΩʔʹͯ͠ ɹassociation ΛΈཱͯΔ
marker.skip? if associations[marker.index] associations[marker.index].add(marker) else associations[marker.index] = Associations.new( marker, @application_associations, @loaded_associations ) end end end end 2023-10-23 07:21:04[WARN] user: makicamel GET /plays USE eager loading detected Play => [:actors] Add to your query: .includes([:actors]) 2023-10-23 07:21:04[WARN] user: makicamel GET /plays USE eager loading detected Play => [:theaters] Add to your query: .includes([:theaters]) ɹෳͷܯࠂΛ ɹͻͱͭʹ·ͱΊ͍ͨ ɹέʔε͕͋Δ
loading detected Actor => [:company] Add to your query: .includes([:company]) Call stack /Users/makicamel/awesome_app/app/views/plays/index.html.erb:3:in `block (2 levels) in _app_views_plays_index_html_erb__2119670124553133993_11760' /Users/makicamel/awesome_app/app/views/plays/index.html.erb:2:in `block in _app_views_plays_index_html_erb__2119670124553133993_11760' /Users/makicamel/awesome_app/app/views/plays/index.html.erb:1:in `_app_views_plays_index_html_erb__2119670124553133993_11760' class PlaysController < ApplicationController def index @plays = Play.includes(:actors) end end ɹҰ෦ includes ࡁͷέʔε LoadedAssociations
loading detected Actor => [:company] Add to your query: .includes([:company]) Call stack /Users/makicamel/awesome_app/app/views/plays/index.html.erb:3:in `block (2 levels) in _app_views_plays_index_html_erb__2119670124553133993_11760' /Users/makicamel/awesome_app/app/views/plays/index.html.erb:2:in `block in _app_views_plays_index_html_erb__2119670124553133993_11760' /Users/makicamel/awesome_app/app/views/plays/index.html.erb:1:in `_app_views_plays_index_html_erb__2119670124553133993_11760' class PlaysController < ApplicationController def index @plays = Play.includes(:actors).includes({:actors=>[:company]}) end end ɹҰ෦ includes ࡁͷέʔε LoadedAssociations
loading detected Actor => [:company] Add to your query: .includes([:company]) Call stack /Users/makicamel/awesome_app/app/views/plays/index.html.erb:3:in `block (2 levels) in _app_views_plays_index_html_erb__2119670124553133993_11760' /Users/makicamel/awesome_app/app/views/plays/index.html.erb:2:in `block in _app_views_plays_index_html_erb__2119670124553133993_11760' /Users/makicamel/awesome_app/app/views/plays/index.html.erb:1:in `_app_views_plays_index_html_erb__2119670124553133993_11760' class PlaysController < ApplicationController def index @plays = Play.includes(:actors).includes({:actors=>[:company]}) end end ɹBullet ͷܯࠂ͔Β ɹ@plays ͷϕʔεͷΫϥε͕ ɹԿ͔Θ͔Βͳ͍ LoadedAssociations
loading detected Actor => [:company] Add to your query: .includes([:company]) Call stack /Users/makicamel/awesome_app/app/views/plays/index.html.erb:3:in `block (2 levels) in _app_views_plays_index_html_erb__2119670124553133993_11760' /Users/makicamel/awesome_app/app/views/plays/index.html.erb:2:in `block in _app_views_plays_index_html_erb__2119670124553133993_11760' /Users/makicamel/awesome_app/app/views/plays/index.html.erb:1:in `_app_views_plays_index_html_erb__2119670124553133993_11760' ɹBullet ͷܯࠂ͔ΒͲͪΒ͕ ɹਖ਼͍͔͠Θ͔Βͳ͍ LoadedAssociations class PlaysController < ApplicationController def index @plays = Play.includes(:actors).includes({:actors=>[:company]}) end end .includes([:company])
Thread.current[:bulletmark_repaier_loaded_associations][model.name][:includes].add(args) super(args) end def eager_load(*args) Thread.current[:bulletmark_repaier_loaded_associations][model.name][:eager_load].add(args) super(args) end def preload(*args) Thread.current[:bulletmark_repaier_loaded_associations][model.name][:preload].add(args) super(args) end end end end ɹಡΈࠐΈࡁͷ associations Λ ɹϝϞ͓ͯ͘͠
loading detected Actor => [:company] Add to your query: .includes([:company]) Call stack /Users/makicamel/awesome_app/app/views/plays/index.html.erb:3:in `block (2 levels) in _app_views_plays_index_html_erb__2119670124553133993_11760' /Users/makicamel/awesome_app/app/views/plays/index.html.erb:2:in `block in _app_views_plays_index_html_erb__2119670124553133993_11760' /Users/makicamel/awesome_app/app/views/plays/index.html.erb:1:in `_app_views_plays_index_html_erb__2119670124553133993_11760' ɹactors includes ࡁͳͷͰ ɹωετ͢Δͷ͕ਖ਼͍͠ 💡 LoadedAssociations class PlaysController < ApplicationController def index @plays = Play.includes(:actors).includes({:actors=>[:company]}) end end .includes([:company])