0

I have a function, Appointment#serializable_hash, that looks like this:

  def serializable_hash(options={})
    options = { 
      :methods => %w( 
        notes
        client
        services
        products
        has_payments
        start_time_ymd
        start_time_time
        calculated_length
        day_of_week_index
        services_with_info
        products_with_info
        payments_with_info
        stylist_name_index
        time_block_type_code
        client_name_that_fits
        minutes_since_midnight
        generous_calculated_length
      )}.update(options)
    super(options)
  end 

When I call the function on an existing Appointment object, the SQL run looks like this:

  Appointment Load (4.6ms)  SELECT "appointment".* FROM "appointment" ORDER BY start_time DESC LIMIT 1
  Appointment Load (0.6ms)  SELECT "appointment".* FROM "appointment" WHERE "appointment"."id" = $1 LIMIT 1  [["id", 4533]]
  Client Load (0.7ms)  SELECT "client".* FROM "client" WHERE "client"."id" = 398 LIMIT 1
  Address Load (0.5ms)  SELECT "address".* FROM "address" WHERE "address"."id" = 10 LIMIT 1
   (15.4ms)  SELECT COUNT(*) FROM "payment" WHERE "payment"."appointment_id" = 4533
  TimeBlockType Load (11.1ms)  SELECT "time_block_type".* FROM "time_block_type" WHERE "time_block_type"."id" = 2 LIMIT 1
  AppointmentService Load (30.3ms)  SELECT "appointment_service".* FROM "appointment_service" WHERE "appointment_service"."appointment_id" = 4533
  Service Load (18.7ms)  SELECT "service".* FROM "service" WHERE "service"."id" = 295 ORDER BY name LIMIT 1
  AppointmentProduct Load (6.2ms)  SELECT "appointment_product".* FROM "appointment_product" WHERE "appointment_product"."appointment_id" = 4533
  Payment Load (0.5ms)  SELECT "payment".* FROM "payment" WHERE "payment"."appointment_id" = 4533
  Stylist Load (15.5ms)  SELECT "stylist".* FROM "stylist" WHERE "stylist"."active" = 't' AND "stylist"."id" = 84 LIMIT 1
  StylistEmploymentType Load (0.7ms)  SELECT "stylist_employment_type".* FROM "stylist_employment_type" WHERE "stylist_employment_type"."code" = 'CHAIR_RENTAL' LIMIT 1
  Salon Load (0.7ms)  SELECT "salon".* FROM "salon" WHERE "salon"."id" = 29 LIMIT 1
  Stylist Load (1.0ms)  SELECT "stylist".* FROM "stylist" WHERE "stylist"."active" = 't' AND (salon_id = 29 AND active = true AND name != 'R.')
  StylistEmploymentType Load (0.3ms)  SELECT "stylist_employment_type".* FROM "stylist_employment_type" WHERE "stylist_employment_type"."code" = 'CHAIR_RENTAL' LIMIT 1
  StylistEmploymentType Load (0.3ms)  SELECT "stylist_employment_type".* FROM "stylist_employment_type" WHERE "stylist_employment_type"."code" = 'CHAIR_RENTAL' LIMIT 1
  StylistEmploymentType Load (0.3ms)  SELECT "stylist_employment_type".* FROM "stylist_employment_type" WHERE "stylist_employment_type"."code" = 'CHAIR_RENTAL' LIMIT 1
  StylistEmploymentType Load (0.3ms)  SELECT "stylist_employment_type".* FROM "stylist_employment_type" WHERE "stylist_employment_type"."code" = 'CHAIR_RENTAL' LIMIT 1
  StylistEmploymentType Load (0.3ms)  SELECT "stylist_employment_type".* FROM "stylist_employment_type" WHERE "stylist_employment_type"."code" = 'CHAIR_RENTAL' LIMIT 1
  StylistEmploymentType Load (0.2ms)  SELECT "stylist_employment_type".* FROM "stylist_employment_type" WHERE "stylist_employment_type"."code" = 'CHAIR_RENTAL' LIMIT 1
  Service Load (3.6ms)  SELECT "service".* FROM "service" INNER JOIN "appointment_service" ON "service"."id" = "appointment_service"."service_id" WHERE "appointment_service"."appointment_id" = 4533 ORDER BY name
  Product Load (16.5ms)  SELECT "product".* FROM "product" INNER JOIN "appointment_product" ON "product"."id" = "appointment_product"."product_id" WHERE "appointment_product"."appointment_id" = 4533 ORDER BY brand_id, name

Obviously, that's less efficient than it could be. How do I get serializable_hash to run in the least number of possible queries? Is there perhaps a better way of doing what I'm doing, not involving serializable_hash?

tereško
  • 58,060
  • 25
  • 98
  • 150
Jason Swett
  • 43,526
  • 67
  • 220
  • 351
  • are you performing some specific task by calling these methods one by one which in turn calling the sql queries? If so, why can't you put that task list in initializer? – sjain Jan 23 '13 at 13:27

1 Answers1

-1

My problem came from a bad design, and I fixed my bad design by using RABL.

Jason Swett
  • 43,526
  • 67
  • 220
  • 351