select-your-own-seat

Expand History Expand History
Collapse History Collapse History

Render Seats for a Venue with SVG elements

The seats#index template iterates over the available sections, rendering <g> elements.

Then, iterating over each Section record’s associated Seat records, renders <circle> elements as children into the Section records’ groups.

The Seat records are rendered as <svg> elements that are positioned with x attributes and y attributes, generated from the Seat record’s x and y columns.

Additionally, dynamically render the name of the current Venue record in the page’s top-left corner.

Desktop

seats rendered as SVG elements

Maintaining acceptable performance

Without being careful, queries like the seats#index action’s query for a collection of section records along with their seat records have the potential to increase our response times, thanks to Performance Regressions caused by N+1 queries.

As a pre-emptive measure, modify the sections query to eager-load related Seat records in a single query by appending a call to includes(:seats).

Before:

Started GET "/venues/benedum_center/floors/orchestra/seats" for 127.0.0.1 at 2020-03-22 18:16:38 -0400
Processing by SeatsController#index as HTML
  Parameters: {"venue_id"=>"benedum_center", "floor_id"=>"orchestra"}
  Venue Load (0.3ms)  SELECT "venues".* FROM "venues" WHERE "venues"."slug" = $1 LIMIT $2  [["slug", "benedum_center"], ["LIMIT", 1]]
  ↳ app/controllers/seats_controller.rb:3:in `index'
  Floor Load (0.2ms)  SELECT "floors".* FROM "floors" WHERE "floors"."venue_id" = $1 AND "floors"."slug" = $2 LIMIT $3  [["venue_id", 487793135], ["slug", "orchestra"], ["LIMIT", 1]]
  ↳ app/controllers/seats_controller.rb:4:in `index'
  Rendering seats/index.html.erb within layouts/application
  Section Load (0.3ms)  SELECT "sections".* FROM "sections" WHERE "sections"."floor_id" = $1  [["floor_id", 155412994]]
  ↳ app/views/seats/index.html.erb:22
  Seat Load (1.4ms)  SELECT "seats".* FROM "seats" WHERE "seats"."section_id" = $1  [["section_id", 725913746]]
  ↳ app/views/seats/index.html.erb:24
  Seat Load (1.3ms)  SELECT "seats".* FROM "seats" WHERE "seats"."section_id" = $1  [["section_id", 531561397]]
  ↳ app/views/seats/index.html.erb:24
  Seat Load (1.4ms)  SELECT "seats".* FROM "seats" WHERE "seats"."section_id" = $1  [["section_id", 171254202]]
  ↳ app/views/seats/index.html.erb:24
  Rendered seats/index.html.erb within layouts/application (Duration: 72.7ms | Allocations: 34553)

Completed 200 OK in 88ms (Views: 80.1ms | ActiveRecord: 4.8ms | Allocations: 42467)

After:

Started GET "/venues/benedum_center/floors/orchestra/seats" for 127.0.0.1 at ...
Processing by SeatsController#index as HTML
  Parameters: {"venue_id"=>"benedum_center", "floor_id"=>"orchestra"}
  Venue Load (0.4ms)  SELECT "venues".* FROM "venues" WHERE "venues"."slug" = $1 LIMIT $2  [["slug", "benedum_center"], ["LIMIT", 1]]
  ↳ app/controllers/seats_controller.rb:3:in `index'
  Floor Load (0.3ms)  SELECT "floors".* FROM "floors" WHERE "floors"."venue_id" = $1 AND "floors"."slug" = $2 LIMIT $3  [["venue_id", 487793135], ["slug", "orchestra"], ["LIMIT", 1]]
  ↳ app/controllers/seats_controller.rb:4:in `index'
  Rendering seats/index.html.erb within layouts/application
  Section Load (0.3ms)  SELECT "sections".* FROM "sections" WHERE "sections"."floor_id" = $1  [["floor_id", 155412994]]
  ↳ app/views/seats/index.html.erb:22
  Seat Load (4.1ms)  SELECT "seats".* FROM "seats" WHERE "seats"."section_id" IN ($1, $2, $3)  [["section_id", 725913746], ["section_id", 531561397], ["section_id", 171254202]]
  ↳ app/views/seats/index.html.erb:22
  Rendered seats/index.html.erb within layouts/application (Duration: 72.3ms | Allocations: 36164)

Completed 200 OK in 84ms (Views: 76.1ms | ActiveRecord: 5.2ms | Allocations: 44188)