Project Revision: Improving ActiveRecord Queries

Christina Sohn
4 min readAug 3, 2020

--

One thing I learned while coding on a project is to reconsider the old saying, “If it ain’t broke, don’t fix it.” When first creating methods, it is a natural impulse to want to keep our code the same once we’ve gotten it to work. After all, we spent plenty of time crafting a certain type of logic and testing different functionalities. However, even though code may technically function correctly (particularly with a small data set), it’s always open to optimization, particularly for speed and efficiency. Therefore, when speaking in terms of code, it may be better to say, “If it ain’t broke, you can still make it better.”

In my first paired-programming, week-long project at Flatiron School, we created an app called Scene It! that lets users search for movie and TV film locations from around the world. Users could also write reviews of these film locations and add their own data for locations or movie/TV shows if they did not yet exist in the database.

Below is a diagram of the different relationships between the tables. To create the tables, we used ActiveRecord migrations and seeded our own data.

After we created functioning code, I went back to review areas where the code could be more efficient.

  1. Converting Ruby enumerables into ActiveRecord queries.

One area of improvement in our code was converting any remaining Ruby enumerables into ActiveRecord queries. As our coach pointed out, when there is a large data set, it will be laborious for a program to loop through “self.all” to find data.

In our original code above, we used the #find enumerable to iterate through all Location instances and find the one that matched the user input for city and country.

In the revised code, we constructed one ActiveRecord query that would search the locations table and necessary information. This query involved inserting raw SQL. This revision reduces the amount of time it would have taken to loop over a large amount of data.

2. Crafting more concise ActiveRecord queries

Once we formulated our initial ActiveRecord queries, it was important to also consider how to make them as efficient and concise as possible. In the original method below, the method prompts and accepts input in the form of a movie location name from the user. We wrote three ActiveRecord queries (lines 65–67) that navigated through two join tables (Movie Locations and Reviews) to eventually find the review that corresponded to the user’s input and the user id.

When our software engineering coach reviewed our code, he pointed out that three queries is not very efficient, particularly if you are working with a large data set. He recommended reducing the number of ActiveRecord queries.

In keeping with his advice, I reviewed the ActiveRecord documentation for “joining tables” and inserted raw SQL code into an ActiveRecord query. By doing this, I was able to reduce the number of ActiveRecord queries and join two tables at once. I was also able to create conditions from two different tables within the #where statement.

However, I continued looking through the documentation to see how I could make these lines more concise. By working backwards from the SQL query, I finally found a way to translate the SQL into clean, concise lines of ActiveRecord code, and perform some ActiveRecord magic!

The final code above shows how “wordy” code can be reduced to its essence by taking advantage of the built-in capabilities of ActiveRecord.

Moral of the story: After you get your code to work, there is always an opportunity to make it better.

Even though code may technically function, it does not necessarily mean that it is in its optimal state. Acting on feedback from more experienced coders can be instrumental in creating more efficient and readable code. Perusing documentation carefully will also lead to magical ways to craft code for complex tasks.

--

--