Talks

Avoiding Pitfalls in Active Record: Practical Usage and Best Practices

Avoiding Pitfalls in Active Record: Practical Usage and Best Practices

by Viktor Schmidt

In the presentation titled "Avoiding Pitfalls in Active Record: Practical Usage and Best Practices," Viktor Schmidt discusses the efficient use of Active Record in Ruby on Rails. Delivered at the Ruby Warsaw Community Conference on July 19, 2024, this talk emphasizes leveraging Active Record effectively to enhance application performance and maintainability.

Key points covered in the presentation include:

  • Understanding Active Record: Schmidt highlights that many developers, especially newcomers, are unfamiliar with effectively using Active Record despite its powerful features.
  • Performance Issues: He shares insights from his experience at Yellow Page, addressing common performance problems caused by improper use of Active Record. He advocates for understanding the implications of using raw SQL versus Active Record, noting that built-in Active Record features often lead to clearer and more maintainable code.
  • Logging and Debugging: The importance of logging is addressed, particularly with the introduction of features in Rails 7.1 for tracking code execution, including the use of the Marginalia gem for enhanced logging.
  • Utilizing Counter Caches: The adoption of counter caches for calculations is discussed, underscoring their utility in improving performance in applications with specific data needs.
  • Active Record Associations: Schmidt stresses the relevance of understanding Active Record associations to structure queries more efficiently, demonstrating this with insights about the has_one relation.
  • Using Subqueries: The talk illustrates how subqueries can be beneficial. It is emphasized that calculations should ideally be performed directly in the database, as this can enhance speed compared to processing in Ruby.
  • Potential of Caching: He notes the necessity of employing caching strategies during peak load to lessen database strain and how gems and tools can facilitate these enhancements.
  • Moving Forward: The importance of continuous learning about Active Record is reinforced, advocating for the development of a robust, maintainable codebase through an improved understanding of its functionalities.

In conclusion, Schmidt encourages developers to embrace the challenges of mastering Active Record fully, as it is vital for achieving better performance and maintainable applications. His insights are rooted in years of professional experience, making this a valuable resource for Ruby on Rails developers seeking to optimize their use of Active Record.

00:00:18.520 Good luck! The stage is yours. Thank you! I was asking last night if I could jump in to present. This presentation was actually done in about three hours, so I skipped the workshop I attended.
00:00:26.000 So, don't expect too much, right? In three hours, you cannot cover everything perfectly. So, let's get a little closer. This presentation is more about how you can use Active Record efficiently. We've heard a lot of information that interacts with each other, and I will share some insights.
00:00:40.200 We'll do a bit of refactoring, but we don't have too much time for that. I'll focus on how to implement this in your daily life, which is probably much better suited for a workshop.
00:00:52.359 You can connect with me if you want. Currently, I work at Yellow Page as a Senior Staff Engineer. Our application is at a stage where we must deal with many Active Record issues.
00:01:05.719 As you know, there are solutions for these issues, but most people, including new engineers joining our company, don't really know how to use Active Record.
00:01:18.640 A little bit about me: I'm originally from Russia, Siberia, where German people live, which is why my last name is Schmidt. Right now, I live in Berlin. I previously served for 12 years as a soldier in different campaigns in the Special Forces and also played esports actively for four years.
00:01:34.280 Currently, I'm also exploring astronomy while working at Yellow Page. When I prepared this presentation over those three hours, I aimed to cover everything, but of course, in 45 minutes, you cannot cover it all.
00:01:49.119 So, the idea is to present the most relevant topics but skip some basics, as most of you are already familiar with them. I'll present more advanced topics, but not too advanced, as many people still don’t know the basics.
00:02:04.520 By basics, I mean everything you see here is based on the Rails Guides—nothing else. Many Rails developers do not realize there are comprehensive Rails Guides available. We also have the Edge Guide, which is often better and contains more details.
00:02:21.160 Let's jump into the first example. You can read quickly through this, but I have consistently seen similar code quality in every project I've worked on over the last five years.
00:02:29.640 During this period, every company has experienced performance issues with Active Record. I have encountered queries that seem normal but do not utilize Active Record effectively.
00:02:43.560 To debug such things or to improve this code is terribly difficult. Let’s compare it with an Active Record approach—it’s much easier to read and understand.
00:02:57.760 Improving performance issues isn’t just about knowledge of SQL, but also fundamentally about understanding the problem. We learned about logging and various tools to help identify the problem first.
00:03:12.120 When you have code in Active Record, it’s much easier to read. You are utilizing built-in features that have been developed by very experienced people—much more experienced than most of us.
00:03:26.479 Most of the Rails core team members have over 20 years of experience in Ruby on Rails. It isn't fair to expect a developer with only five years of experience to know everything.
00:03:40.600 That’s why using Active Record is a better approach. You access built-in features that are both performant and understandable.
00:03:55.199 Do you agree? Sometimes, it might just be easier to write raw SQL.
00:04:05.039 Totally agree! It’s a good point. Most of the people I’ve worked with have operated differently from me—I'm used to working in the console.
00:04:14.440 There, you can execute Active Record commands easily. Just add a line in the console for debugging, and you can utilize Active Record without issues.
00:04:23.720 But yes, I understand your point that sometimes it’s easier to write SQL if you are familiar with it and less familiar with Active Record.
00:04:30.080 Let’s move on to the second topic: logging. We had John’s ideas about logging, and now I want to discuss frameworks to track code execution.
00:04:44.560 Finding the code we discussed is indeed really challenging. There are some features in Rails, notably from version 7.1 onward, where you can add annotations.
00:04:56.200 You might also know about a gem called Marginalia, which logs the execution place of the queries run by Active Record.
00:05:05.039 It's an important feature because if you're executing normal SQL, you won't get this information. In Rails 7, logging is integrated by default.
00:05:18.239 Now, let’s talk about counter caches. At Yellow Page, we have many calculations to perform. We don’t have large amounts of data compared to other companies, yet those calculations can slow things down.
00:05:36.440 I often ask how other companies manage this, and there are solutions in Ruby on Rails for calculating and utilizing pre-calculated values. While there are downsides, most times, it’s much quicker when done correctly.
00:05:52.760 How many people here use Active Record in their applications? Only four? That’s about what I expected, as most people don’t seem to understand its potential.
00:06:08.559 It’s an important concept that can considerably speed up our applications. Moving on to joint types, just two weeks ago I internally presented on this again to our Yellow Page developers.
00:06:20.799 We have meetings every week, and during one of these sessions with about 50 backend developers, I was surprised that no one understood the topic of Active Record associations.
00:06:35.760 I’ll show you some insights that, while they should be obvious, seem to have eluded many developers. You might be familiar with them.
00:06:49.880 For instance, has_one relations have a specific behavior that can be helpful, especially when ordering records.
00:07:05.840 Most times, you don’t need a has_one relation directly; it’s about how you structure your queries. Selecting fields wisely can reduce unnecessary input/output operations, improving performance.
00:07:19.680 Speaking of performance, one feature I think many people aren't aware of is returning values after an insert operation, which isn’t available in Active Record until version 7.2.
00:07:34.560 Utilizing Active Record effectively allows for better performance and maintainability as it reduces the amount of background querying.
00:07:49.440 We’ve had many instances in the past where subqueries lead to major performance bottlenecks, so it’s critical to understand when to use raw SQL.
00:08:04.239 Calculations in the database are often faster than running them in Ruby, which is why I emphasize using the database for heavy-duty calculations whenever possible.
00:08:20.320 Many developers, however, overlook this, opting to perform tasks in Ruby instead. We need to leverage the database's capabilities.
00:08:35.600 Using subqueries in Active Record can be efficient, and knowing how to integrate these effectively with Active Record is crucial.
00:08:46.880 Indeed, calculating at the database level provides a significant speed improvement over Ruby-based calculations.
00:09:01.280 We've learned that using Active Record in conjunction with proper SQL can enhance our application’s performance without the need to restructure everything.
00:09:18.680 I need to emphasize that material views, although beneficial, do require consistent updates. In my experience, it's essential to refresh these regularly to obtain the performance boost they promise.
00:09:35.920 As we continue to explore performance, I want to mention the need for appropriate caching strategies to prevent strain on the database during high-load periods.
00:09:49.440 We should consider the quickly changing landscape of data interactions and be prepared for varying performance needs based on application demands.
00:10:06.440 Also, it’s good to keep an eye on various gems and tools that can help streamline these processes and improve overall efficiency.
00:10:22.479 As we look at storage procedures, active support for these in Rails remains limited, yet it is something many developers have yearned for.
00:10:39.559 Every solution is unique, and there often isn’t a one-size-fits-all answer, especially regarding proper performance optimization.
00:10:54.600 Tools such as Active Record provide foundational capabilities, yet developers need to understand and extend their application’s potential.
00:11:11.799 While I don’t think we have all the answers now, we certainly have a strong foundation to build on moving forward in our journey with Rails.
00:11:24.679 And finally, remember that despite challenges in understanding and utilizing Active Record's full potential, it’s worth the effort to improve your understanding over time.
00:11:40.240 Not only will it improve your performance, but it also leads to a more robust and maintainable codebase. Let’s keep pushing forward and exploring the best practices.
00:11:58.680 Thank you for your attention.