Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CRUD! Dear Active Record, It's Not You, It's Me

CRUD! Dear Active Record, It's Not You, It's Me

Eileen M. Uchitelle

June 06, 2014
Tweet

More Decks by Eileen M. Uchitelle

Other Decks in Technology

Transcript

  1. But I knew Active Record and I could work it

    out So I began studying my queries more closely...
  2. Address Book Example ERD Users first_name string last_name string email

    string password_digest string ...[etc] Contacts first_name string last_name string birthday date user_id integer ...[etc] Categories name string description string user_id integer Categorizations contact_id integer category_id integer
  3. Address Book Example User has_many :contacts has_many :categories Contact belongs_to

    :user has_many :categorizations, dependent: :delete_all has_many :categories, through: :categorizations Category belongs_to :user has_many :categorizations, dependent: :delete_all has_many :contacts, through: :categorizations Categorizations belongs_to :contact belongs_to :category
  4. Address Book Example User has_many :contacts has_many :categories Contact belongs_to

    :user has_many :categorizations, dependent: :delete_all has_many :categories, through: :categorizations Category belongs_to :user has_many :categorizations, dependent: :delete_all has_many :contacts, through: :categorizations Categorizations belongs_to :contact belongs_to :category
  5. Address Book Example User has_many :contacts has_many :categories Contact belongs_to

    :user has_many :categorizations, dependent: :delete_all has_many :categories, through: :categorizations Category belongs_to :user has_many :categorizations, dependent: :delete_all has_many :contacts, through: :categorizations Categorizations belongs_to :contact belongs_to :category
  6. Address Book Example User has_many :contacts has_many :categories Contact belongs_to

    :user has_many :categorizations, dependent: :delete_all has_many :categories, through: :categorizations Category belongs_to :user has_many :categorizations, dependent: :delete_all has_many :contacts, through: :categorizations Categorizations belongs_to :contact belongs_to :category
  7. Address Book Example User has_many :contacts has_many :categories Contact belongs_to

    :user has_many :categorizations, dependent: :delete_all has_many :categories, through: :categorizations Category belongs_to :user has_many :categorizations, dependent: :delete_all has_many :contacts, through: :categorizations Categorizations belongs_to :contact belongs_to :category
  8. Let’s create 10,000 records the Active Record way using a

    CSV CSV.foreach("#{filepath}", headers: true) do |csv| Contact.create!({ first_name: csv[0], last_name: csv[1], birthday: csv[2], ... }) end
  9. Let’s create 10,000 records the Active Record way using a

    CSV CSV.foreach("#{filepath}", headers: true) do |csv| Contact.create!({ first_name: csv[0], last_name: csv[1], birthday: csv[2], ... }) end INSERT INTO `contacts` (`first_name`, `last_name`, `birthday`,...) VALUES ('John', 'Smith', '1987-02-01',...);
  10. Let’s create the same contacts with MySQL Batch Insert contact_values

    = [] CSV.foreach("#{filepath}", headers: true) do |csv| contact_values << "('#{csv[0]}','#{csv[1]}','#{csv[2]}'...)" end batch_size = 2000 while !contact_values.empty? contacts_shifted = contact_values.shift(batch_size) contacts_sql = "INSERT INTO contacts(first_name, last_name, birthday,...) VALUES#{contacts_shifted.join(", ")}" ActiveRecord::Base.connection.execute(contacts_sql) end
  11. Let’s create the same contacts with MySQL Batch Insert contact_values

    = [] CSV.foreach("#{filepath}", headers: true) do |csv| contact_values << "('#{csv[0]}','#{csv[1]}','#{csv[2]}'...)" end batch_size = 2000 while !contact_values.empty? contacts_shifted = contact_values.shift(batch_size) contacts_sql = "INSERT INTO contacts(first_name, last_name, birthday,...) VALUES#{contacts_shifted.join(", ")}" ActiveRecord::Base.connection.execute(contacts_sql) end
  12. Let’s create the same contacts with MySQL Batch Insert contact_values

    = [] CSV.foreach("#{filepath}", headers: true) do |csv| contact_values << "('#{csv[0]}','#{csv[1]}','#{csv[2]}'...)" end batch_size = 2000 while !contact_values.empty? contacts_shifted = contact_values.shift(batch_size) contacts_sql = "INSERT INTO contacts(first_name, last_name, birthday,...) VALUES#{contacts_shifted.join(", ")}" ActiveRecord::Base.connection.execute(contacts_sql) end
  13. Let’s create the same contacts with MySQL Batch Insert contact_values

    = [] CSV.foreach("#{filepath}", headers: true) do |csv| contact_values << "('#{csv[0]}','#{csv[1]}','#{csv[2]}'...)" end batch_size = 2000 while !contact_values.empty? contacts_shifted = contact_values.shift(batch_size) contacts_sql = "INSERT INTO contacts(first_name, last_name, birthday,...) VALUES#{contacts_shifted.join(", ")}" ActiveRecord::Base.connection.execute(contacts_sql) end
  14. Let’s create the same contacts with MySQL Batch Insert contact_values

    = [] CSV.foreach("#{filepath}", headers: true) do |csv| contact_values << "('#{csv[0]}','#{csv[1]}','#{csv[2]}'...)" end batch_size = 2000 while !contact_values.empty? contacts_shifted = contact_values.shift(batch_size) contacts_sql = "INSERT INTO contacts(first_name, last_name, birthday,...) VALUES#{contacts_shifted.join(", ")}" ActiveRecord::Base.connection.execute(contacts_sql) end
  15. Let’s create the same contacts with MySQL Batch Insert contact_values

    = [] CSV.foreach("#{filepath}", headers: true) do |csv| contact_values << "('#{csv[0]}','#{csv[1]}','#{csv[2]}'...)" end batch_size = 2000 while !contact_values.empty? contacts_shifted = contact_values.shift(batch_size) contacts_sql = "INSERT INTO contacts(first_name, last_name, birthday,...) VALUES#{contacts_shifted.join(", ")}" ActiveRecord::Base.connection.execute(contacts_sql) end
  16. Let’s create the same contacts with MySQL Batch Insert ActiveRecord::Base.connection.execute(contacts_sql)

    INSERT INTO contacts(first_name, last_name, birthday,...) VALUES('Lauretta','Senger','1987-02-01',...), ('Jane','Roob','1987-02-01',...), ('Blaze','Lakin','1987-02-01',...), ('Elton','Cormier','1987-02-01',...), ('John','Kohler','1987-02-01',...), ('Clementine','Marvin','1987-02-01',...), ('Ova','Aufderhar','1987-02-01',...) ...
  17. That’s a huge difference Active Record Benchmark Data: user system

    total real => 44.740000 1.180000 45.920000 ( 51.095556)
  18. That’s a huge difference Active Record Benchmark Data: user system

    total real => 44.740000 1.180000 45.920000 ( 51.095556) MySQL Batch Insert Benchmark Data: user system total real => 2.710000 0.050000 2.760000 ( 3.227031)
  19. That’s a huge difference Active Record Benchmark Data: user system

    total real => 44.740000 1.180000 45.920000 ( 51.095556) MySQL Batch Insert Benchmark Data: user system total real => 2.710000 0.050000 2.760000 ( 3.227031)
  20. Let’s read some data and output the first name of

    each contact Contact.where(user_id: 1, country: “USA”).each do |contact| puts contact.first_name end Contact.where(user_id: 1, country: “USA”).find_each do |contact| puts contact.first_name end Contact.where(user_id: 1, country: “USA”) .pluck(:first_name).each do |first_name| puts first_name end
  21. Let’s read some data and output the first name of

    each contact Contact.where(user_id: 1, country: “USA”).each do |contact| puts contact.first_name end SELECT `contacts`.* FROM `contacts` WHERE `contacts`.`user_id` = 1 AND `contacts`.`country` = 'USA' => Lauretta Shana Jason Jermain Blaze Jessy Bradly ...
  22. Let’s read some data and output the first name of

    each contact Contact.where(user_id: 1, country: “USA”).find_each do |contact| puts contact.first_name end SELECT `contacts`.* FROM `contacts` WHERE `contacts`.`user_id` = 1 AND `contacts`.`country` = 'USA' ORDER BY `contacts`.`id` ASC LIMIT 1000 => Lauretta Shana Jason ... SELECT `contacts`.* FROM `contacts` WHERE `contacts`.`user_id` = 1 AND `contacts`.`country` = 'USA' AND (`contacts`.`id` > 1001) ORDER BY `contacts`.`id` ASC LIMIT 1000 => ...
  23. Let’s read some data and output the first name of

    each contact f Contact.where(user_id: 1, country: “USA”) .pluck(:first_name).each do |first_name| puts first_name end SELECT `contacts`.`first_name` FROM `contacts` WHERE `contacts`.`user_id` = 1 AND `contacts`.`country` = 'USA' => ["Lauretta", "Shana", "Jason", "Jermain", "Blaze", "Jessy", "Bradly", "Emma", "Cruz", "Elton", "Dashawn", "Rosanna", "Ryan", "Leonel", "Ashly", "Mittie", "Tobin", "Antonio", "Chad", "Lauryn", "Sydnie", "Sebastian", "Johnpaul", "Yasmeen", "Junior", "Monroe", "Avery",...]
  24. Let’s read some data and output the first name of

    each contact Contact.where(user_id: 1, country: “USA”).each do |contact| puts contact.first_name end Contact.where(user_id: 1, country: “USA”).find_each do |contact| puts contact.first_name end Contact.where(user_id: 1, country: “USA”) .pluck(:first_name).each do |first_name| puts first_name end
  25. Which one was fastest? .each Benchmark Data: user system total

    real => 0.950000 0.060000 1.010000 ( 1.050266)
  26. Which one was fastest? .each Benchmark Data: user system total

    real => 0.950000 0.060000 1.010000 ( 1.050266) .find_each Benchmark Data: user system total real => 0.900000 0.040000 0.940000 ( 0.976979)
  27. Which one was fastest? .each Benchmark Data: user system total

    real => 0.950000 0.060000 1.010000 ( 1.050266) .find_each Benchmark Data: user system total real => 0.900000 0.040000 0.940000 ( 0.976979) .pluck Benchmark Data: user system total real => 0.080000 0.020000 0.100000 ( 0.126814)
  28. Which one was fastest? .each Benchmark Data: user system total

    real => 0.950000 0.060000 1.010000 ( 1.050266) .find_each Benchmark Data: user system total real => 0.900000 0.040000 0.940000 ( 0.976979) .pluck Benchmark Data: user system total real => 0.080000 0.020000 0.100000 ( 0.126814)
  29. Which one was fastest? .each Benchmark Data: user system total

    real => 0.950000 0.060000 1.010000 ( 1.050266) .find_each Benchmark Data: user system total real => 0.900000 0.040000 0.940000 ( 0.976979) .pluck Benchmark Data: user system total real => 0.080000 0.020000 0.100000 ( 0.126814)
  30. Which one was fastest? .each Benchmark Data: user system total

    real => 0.950000 0.060000 1.010000 ( 1.050266) .find_each Benchmark Data: user system total real => 0.900000 0.040000 0.940000 ( 0.976979) .pluck Benchmark Data: user system total real => 0.080000 0.020000 0.100000 ( 0.126814)
  31. Statistics for Read 0 3.8 7.5 11.3 15.0 0 10

    1000 10000 100000 .each .find_each .pluck
  32. Utilizing find_by_sql Contact.find_by_sql([ "SELECT first_name FROM contacts WHERE user_id=? AND

    country=? AND birthday > ?", 1, 'USA','1987-01-01' ]).each do |contact| puts contact.first_name end
  33. Let’s update the category in each categorization category = Category.where(name:

    “Networking”).first Categorization.all.each do |categorization| categorization.update_attributes( category_id: category.id ) end
  34. Let’s update the category in each categorization category = Category.where(name:

    “Networking”).first Categorization.all.each do |categorization| categorization.update_attributes( category_id: category.id ) end UPDATE `categorizations` SET `category_id` = 1 WHERE `categorizations`.`id` = 1 UPDATE `categorizations` SET `category_id` = 1 WHERE `categorizations`.`id` = 2 UPDATE `categorizations` SET `category_id` = 1 WHERE `categorizations`.`id` = 3
  35. Let’s update the category in each categorization category = Category.where(name:

    “Networking”).first Categorization.update_all( category_id: category.id )
  36. Let’s update the category in each categorization category = Category.where(name:

    “Networking”).first Categorization.update_all( category_id: category.id ) UPDATE `categorizations` SET `categorizations`.`category_id` = 1
  37. Check out the difference update_attributes Benchmark Data: user system total

    real => 12.990000 0.870000 13.860000 ( 17.156265)
  38. Check out the difference update_attributes Benchmark Data: user system total

    real => 12.990000 0.870000 13.860000 ( 17.156265) update_all Benchmark Data: user system total real => 0.000000 0.000000 0.000000 ( 0.042140)
  39. Check out the difference update_attributes Benchmark Data: user system total

    real => 12.990000 0.870000 13.860000 ( 17.156265) update_all Benchmark Data: user system total real => 0.000000 0.000000 0.000000 ( 0.042140)
  40. destroy_all vs. delete_all with has_many dependencies Contact has_many :categorizations has_many

    :categories, through: :categorizations Category has_many :categorizations has_many :contacts, through: :categorizations Categorizations belongs_to :contact belongs_to :category
  41. f f destroy_all vs. delete_all with has_many dependencies Contact has_many

    :categorizations, dependent: :destroy has_many :categories, through: :categorizations Category has_many :categorizations, dependent: :destroy has_many :contacts, through: :categorizations Contact.destroy_all
  42. destroy_all vs. delete_all with has_many dependencies f f Contact has_many

    :categorizations, dependent: :destroy has_many :categories, through: :categorizations Category has_many :categorizations, dependent: :destroy has_many :contacts, through: :categorizations Contact.destroy_all SELECT `categorizations`.* FROM `categorizations` WHERE `categorizations`.`contact_id` = 1 DELETE FROM `categorizations` WHERE `categorizations`.`id` = 1 DELETE FROM `contacts` WHERE `contacts`.`id` = 1
  43. destroy_all vs. delete_all with has_many dependencies f f Contact has_many

    :categorizations, dependent: :delete_all has_many :categories, through: :categorizations Category has_many :categorizations, dependent: :delete_all has_many :contacts, through: :categorizations Contact.delete_all
  44. destroy_all vs. delete_all with has_many dependencies f f Contact has_many

    :categorizations, dependent: :delete_all has_many :categories, through: :categorizations Category has_many :categorizations, dependent: :delete_all has_many :contacts, through: :categorizations Contact.delete_all DELETE FROM `contacts`
  45. destroy_all vs. delete_all with has_many dependencies f f Contact has_many

    :categorizations has_many :categories, through: :categorizations Category has_many :categorizations has_many :contacts, through: :categorizations Contact.delete_all Contact.destroy_all
  46. destroy_all vs. delete_all with has_many dependencies f f Contact has_many

    :categorizations has_many :categories, through: :categorizations Category has_many :categorizations has_many :contacts, through: :categorizations Contact.delete_all DELETE FROM `contacts` Contact.destroy_all
  47. destroy_all vs. delete_all with has_many dependencies f f Contact has_many

    :categorizations has_many :categories, through: :categorizations Category has_many :categorizations has_many :contacts, through: :categorizations Contact.delete_all Contact.destroy_all DELETE FROM `contacts` WHERE `contacts`.`id` = 1 DELETE FROM `contacts` WHERE `contacts`.`id` = 2 DELETE FROM `contacts` WHERE `contacts`.`id` = 3
  48. destroy_all vs. delete_all with has_many dependencies category = Category.where(name: “Networking”).first

    category.contacts.destroy_all It looks like you’re trying to delete some records, do you need help with that?
  49. destroy_all vs. delete_all with has_many dependencies category = Category.where(name: “Networking”).first

    category.contacts.destroy_all category.categorizations.destroy_all It looks like you’re trying to delete some records, do you need help with that?
  50. destroy_all vs. delete_all with has_many dependencies category = Category.where(name: “Networking”).first

    category.contacts.destroy_all category.categorizations.destroy_all category.categorizations.delete_all It looks like you’re trying to delete some records, do you need help with that?
  51. destroy_all vs. delete_all with has_many dependencies f f Contact has_many

    :categorizations has_many :categories, through: :categorizations Category has_many :categorizations has_many :contacts, through: :categorizations category.categorizations.delete_all
  52. destroy_all vs. delete_all with has_many dependencies f f Contact has_many

    :categorizations has_many :categories, through: :categorizations Category has_many :categorizations has_many :contacts, through: :categorizations category.categorizations.delete_all UPDATE `categorizations` SET `categorizations`.`category_id` = NULL WHERE `categorizations`.`category_id` = 1 AND `categorizations`.`id` IN (1, 2, 3, 4, 5, 6...10000)
  53. destroy_all vs. delete_all with has_many dependencies Contact has_many :categorizations, dependent:

    :destroy has_many :categories, through: :categorizations Category has_many :categorizations, dependent: :destroy has_many :contacts, through: :categorizations category.categorizations.delete_all f f
  54. destroy_all vs. delete_all with has_many dependencies Contact has_many :categorizations, dependent:

    :destroy has_many :categories, through: :categorizations Category has_many :categorizations, dependent: :destroy has_many :contacts, through: :categorizations category.categorizations.delete_all DELETE FROM `categorizations` WHERE `categorizations`.`id` = 1 DELETE FROM `categorizations` WHERE `categorizations`.`id` = 2... f f
  55. destroy_all vs. delete_all with has_many dependencies f f Contact has_many

    :categorizations, dependent: :delete_all has_many :categories, through: :categorizations Category has_many :categorizations, dependent: :delete_all has_many :contacts, through: :categorizations category.categorizations.delete_all
  56. destroy_all vs. delete_all with has_many dependencies category.categorizations.delete_all user system total

    real => 130.080000 0.120000 130.200000 (130.308334) DELETE FROM `categorizations` WHERE `categorizations`.`category_id` = 1
  57. destroy_all vs. delete_all with has_many dependencies category.categorizations.delete_all user system total

    real => 130.080000 0.120000 130.200000 (130.308334) DELETE FROM `categorizations` WHERE `categorizations`.`category_id` = 1 AND `categorizations`.`id` IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46...10000)
  58. Solutions to this problem category = Category.where(name: “Networking”).first Categorization.where( category_id:

    category.id).delete_all user system total real => 0.010000 0.000000 0.010000 ( 0.014286)
  59. Solutions to this problem category = Category.where(name: “Networking”).first Categorization.where( category_id:

    category.id).delete_all user system total real => 0.010000 0.000000 0.010000 ( 0.014286) DELETE FROM `categorizations` WHERE `categorizations`.`category_id` = 1
  60. delete_all behavior with has_many dependencies in Rails 4.2+ Contact has_many

    :categorizations, dependent: :destroy has_many :categories, through: :categorizations Category has_many :categorizations, dependent: :destroy has_many :contacts, through: :categorizations category.categorizations.delete_all DELETE FROM `categorizations` WHERE `categorizations`.`id` = 1 DELETE FROM `categorizations` WHERE `categorizations`.`id` = 2... f f
  61. delete_all behavior with has_many dependencies in Rails 4.2+ Contact has_many

    :categorizations, dependent: :destroy has_many :categories, through: :categorizations Category has_many :categorizations, dependent: :destroy has_many :contacts, through: :categorizations category.categorizations.delete_all DELETE FROM `categorizations` WHERE `categorizations`.`category_id` = 1 Thanks to @neerajdotname for this pull request f f
  62. delete_all behavior with has_many dependencies in Rails 4.2+ Contact has_many

    :categorizations, dependent: :delete_all has_many :categories, through: :categorizations Category has_many :categorizations, dependent: :delete_all has_many :contacts, through: :categorizations category.categorizations.delete_all DELETE FROM `categorizations` WHERE `categorizations`.`category_id` = 1 AND `categorizations`.`id` IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,...10000) f f
  63. delete_all behavior with has_many dependencies in Rails 4.2+ Contact has_many

    :categorizations, dependent: :delete_all has_many :categories, through: :categorizations Category has_many :categorizations, dependent: :delete_all has_many :contacts, through: :categorizations category.categorizations.delete_all DELETE FROM `categorizations` WHERE `categorizations`.`category_id` = 1 f f
  64. delete_all behavior with has_many dependencies in Rails 4.2+ f f

    Contact has_many :categorizations has_many :categories, through: :categorizations Category has_many :categorizations has_many :contacts, through: :categorizations category.categorizations.delete_all UPDATE `categorizations` SET `categorizations`.`category_id` = NULL WHERE `categorizations`.`category_id` = 1 AND `categorizations`.`id` IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,...10000)
  65. delete_all behavior with has_many dependencies in Rails 4.2+ f f

    Contact has_many :categorizations has_many :categories, through: :categorizations Category has_many :categorizations has_many :contacts, through: :categorizations category.categorizations.delete_all UPDATE `categorizations` SET `categorizations`.`category_id` = NULL WHERE `categorizations`.`category_id` = 1
  66. Comparison of delete_all from 4.0 to 4.2 Version SQL Callbacks

    4.1 & below no dependency UPDATE `categorizations` SET `categorizations`.`category_id` = NULL WHERE `categorizations`.`category_id` = 1 AND `categorizations`.`id` IN (1, 2, 3, 4, 5... NO destroy DELETE FROM `categorizations` WHERE `categorizations`.`id` = 1 YES delete_all DELETE FROM `categorizations` WHERE `categorizations`.`category_id` = 1 AND `categorizations`.`id` IN (1, 2, 3, 4, 5... NO 4.2+ no dependency UPDATE `categorizations` SET `categorizations`.`category_id` = NULL WHERE `categorizations`.`category_id` = 1 NO destroy DELETE FROM `categorizations` WHERE `categorizations`.`category_id` = 1 NO delete_all DELETE FROM `categorizations` WHERE `categorizations`.`category_id` = 1 NO
  67. File: activerecord/lib/active_record/ associations/collection_association.rb # => Rails 4.0 - 4.1 def

    delete_all(dependent = nil) [...] dependent = [...] delete(:all, dependent: dependent).tap do reset loaded! end end
  68. File: activerecord/lib/active_record/ associations/collection_association.rb # => Rails 4.0 - 4.1 def

    delete_all(dependent = nil) [...] dependent = [...] delete(:all, dependent: dependent).tap do reset loaded! end end f
  69. File: activerecord/lib/active_record/ associations/collection_association.rb # => Rails 4.0 - 4.1 def

    delete(*records) dependent = options[:dependent] if records.first == :all if loaded? || dependent == :destroy delete_or_destroy(load_target, dependent) else delete_records(:all, dependent) end else... end end
  70. f File: activerecord/lib/active_record/ associations/collection_association.rb # => Rails 4.0 - 4.1

    def delete(*records) dependent = options[:dependent] if records.first == :all if loaded? || dependent == :destroy delete_or_destroy(load_target, dependent) else delete_records(:all, dependent) end else... end end
  71. f File: activerecord/lib/active_record/ associations/collection_association.rb # => Rails 4.2+ def delete_all(dependent

    = nil) [...] dependent = [...] - delete(:all, dependent: dependent).tap do + delete_records(:all, dependent: dependent).tap do reset loaded! end end
  72. File: activerecord/lib/active_record/ associations/collection_association.rb # => Rails 4.2+ def delete(*records) dependent

    = options[:dependent] if records.first == :all if loaded? || dependent == :destroy delete_or_destroy(load_target, dependent) else delete_records(:all, dependent) end else... end end - - - - - - - -
  73. File: activerecord/lib/active_record/ associations/has_many_association.rb # => Rails 4.2+ def delete_or_nullify_all_records(method) count

    = delete_count(method, self.scope) update_counter(-count) end def delete_records(records, method) if method == :destroy records.each(&:destroy!) update_counter(-records.length) unless ... else scope = self.scope.where(reflection.klass.primary_key ... update_counter(-delete_count(method, scope)) end end
  74. f File: activerecord/lib/active_record/ associations/collection_association.rb # => Rails 4.2+ def delete_all(dependent

    = nil) [...] dependent = [...] - delete_records(:all, dependent: dependent).tap do + delete_or_nullify_all_records(dependent).tap do reset loaded! end end
  75. Check out these helpful tools ‣ New Relic rewrelic.com ‣

    MiniProfiler github.com/MiniProfiler/rack-mini-profiler
  76. Check out these helpful tools ‣ New Relic rewrelic.com ‣

    MiniProfiler github.com/MiniProfiler/rack-mini-profiler ‣ Bullet Gem github.com/flyerhzm/bullet