2

I currently have a page that takes 11 seconds to load. I'm using the Bullet Gem to help me find where the N+1 query is happening. Its giving my some output but I really don't know what to do with it. Here is the output from Bullet:

GET /events/1679/dashboard
USE eager loading detected
  RSVP => [:tickets]
  Add to your finder: :includes => [:tickets]
Call stack
  /Users/cameronbass/Desktop/Work/blackbird-rsvp/app/decorators/rsvp_decorator.rb:54:in `tickets?'
  /Users/cameronbass/Desktop/Work/blackbird-rsvp/app/views/accepted_rsvps/_list.html.erb:33:in `block in _app_views_accepted_rsvps__list_html_erb___1211423417683052584_70339569780320'

And it's telling me to put it on this line

def tickets?
  rsvp.tickets.any?
end

Here is the association:

has_many :tickets, through: :attendees

attendee.rb

has_one :ticket
Ilya Lavrov
  • 2,810
  • 3
  • 20
  • 37
Bitwise
  • 8,021
  • 22
  • 70
  • 161
  • 1
    Normally this refers to something iterating over a list of those things and calling `tickets?` on each one. That code is not shown but presumably you have a list of mulitiple...whatever these are. – tadman Apr 18 '17 at 19:08
  • 1
    Look at your logs! When you see the database being hit many times for one request you probably have an N+1 situation. You can use eager loading to instead hit the db just once to grab the associated table and then load the records. – bkunzi01 Apr 18 '17 at 19:16
  • 1
    When I see questions like this, I feel obliged to link to this answer: http://stackoverflow.com/a/26251892/525478. YMMV – Brad Werth Apr 18 '17 at 20:57

1 Answers1

5

Bullet points you to the place where it detected multiple calls of the same association, not to the place where you should add eager loading.

Somewhere in the _list.html.erb template you probably traverse your RSVPs (whatever that is) and for each RSVP you are trying to determine whether it has any ticket or not by calling the tickets association.

Bullet advices you to add include(:tickets) to the finder which sets up the variable for RSVPs (probably somewhere in your AcceptedRSVPs controller) that you traverse in the template. Once that is done, there won't be an SQL run for each RSVP to find out its tickets and thus you'll get rid of the N+1 problem.

Matouš Borák
  • 15,606
  • 1
  • 42
  • 53