# Stupid Simple ActiveRecord Optimizations or Why Rails Console is Essential for Development

DevFeed: [Stupid Simple ActiveRecord Optimizations or Why Rails Console is Essential for Development](<https://devfeed.tech/articles/stupid-simple-activerecord-optimizations-or-why-rails-console-is-essential-for-development-28241.md>)

Original publisher: [Read original article](<http://fuzzyblog.io/blog/rails/2019/11/05/stupid-simple-activerecord-optimizations-or-why-rails-console-is-essential-for-development.html>)

Author: Fuzzygroup

Published: 2019-11-05T00:00:00Z

Content type: tutorial

Language: en

Sources: [Scott Johnson](<https://devfeed.tech/sources/scott-johnson.md>)

Topics: [Rails](<https://devfeed.tech/topics/rails.md>), [Optimization](<https://devfeed.tech/topics/optimization.md>), [Development](<https://devfeed.tech/topics/development.md>), [Database](<https://devfeed.tech/topics/database.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [active-record](<https://devfeed.tech/tags/active-record.md>), [activerecord](<https://devfeed.tech/tags/activerecord.md>), [code](<https://devfeed.tech/tags/code.md>), [console](<https://devfeed.tech/tags/console.md>), [database](<https://devfeed.tech/tags/database.md>), [development](<https://devfeed.tech/tags/development.md>), [optimization](<https://devfeed.tech/tags/optimization.md>), [rails](<https://devfeed.tech/tags/rails.md>)

## AI overview

The article explains how Rails console can reveal repeated database queries caused by repeated ActiveRecord association access. It demonstrates rewriting a method to store the associated goal in a local variable, reducing repeated reads and potentially improving both production and development performance without relying on server-side caching.

## Source excerpt

Ever since 2008 when my pairing partner at the time, Jared, pushed me to basically live in the Rails console, I've been heavily, heavily dependent on the console as an essential developer tool. I just watched something that pointed out to me just why it is so damn important. Here's what I observed: 2.6.3 :057 > m.change_pct_today_over_goal? Goal Load (65.2ms) SELECT `goals`.* FROM `goals` WHERE `goals`.`habit_id` = 39 ORDER BY `goals`.`id` ASC LIMIT 1 Habit Load (0.4ms) SELECT `habits`.* FROM `habits` WHERE `habits`.`id` = 39 LIMIT 1 Goal Load (0.5ms) SELECT `goals`.* FROM `goals` WHERE `goals`.`habit_id` = 39 ORDER BY `goals`.`id` ASC LIMIT 1 Goal Load (30.2ms) SELECT `goals`.* FROM `goals` WHERE `goals`.`habit_id` = 39 ORDER BY `goals`.`id` ASC LIMIT 1 true I simply can't think that the fact that we're loading the goal from the database 3 times is an optimal use of computing resources. So I dug into the code and here's what I saw: # original def change_pct_today_over_goal? return false if self.goal.nil? return false if self.habit.goal.amount.nil? goal_amount = self.goal.amount.to_f actual_amount = self.amount amount_over_goal = actual_amount - goal_amount return false if amount_over_goal < 0 return false if amount_over_goal == 0 return true if (amount_over_goal / goal_amount).to_f * 100 >= 25.0 return false end The first 3 lines in the method above walk database associations back to the goal. The simple optimization is to store the goal in a local variable so it is only read once: # rewritten def change_pct_today_over_goal? goal = self.goal return false if goal.nil? return false if goal.amount.nil? goal_amount = goal.amount.to_f actual_amount = self.amount amount_over_goal = actual_amount - goal_amount return false if amount_over_goal < 0 return false if amount_over_goal == 0 return true if (amount_over_goal / goal_amount).to_f * 100 >= 25.0 return false end Now it is possible that with the right caching strategy server side, this change wouldn't be necessary but