RailsConf 2022

Browser History Confessional: Searching My Recent Searches

Browser History Confessional: Searching My Recent Searches

by Kevin Murphy

In the video titled "Browser History Confessional: Searching My Recent Searches," Kevin Murphy addresses the importance of effective search strategies in software development, particularly in resolving challenges in coding. Presenting at RailsConf 2022, he emphasizes that developers frequently utilize search engines to find solutions to issues, and understanding the underlying reasons for these searches can lead to more efficient problem-solving.

Key Points Discussed:

  • Understanding the Reasons for Searching: Murphy encourages viewers to reflect on the motivations behind their searches, which can help in narrowing down results and achieving quicker resolutions.
  • Introducing Alluvial: He shares about a personalized search engine he developed called Alluvial, which allows users to access tailored search results, limit queries to three outcomes, and track their search history across devices and browsers.
  • Iterative Development: Murphy takes the audience through a coding example where he integrates Rails' features into a view component, illustrating the process of timestamping search results and enhancing user experience.
  • Troubleshooting Techniques: He discusses various scenarios in troubleshooting, such as handling errors in Rails applications. Utilizing different documentation resources effectively is highlighted as a vital skill.
  • Collaborative Problem-Solving: The importance of seeking help from colleagues and the community is underscored. Murphy shares a personal anecdote about reaching out to a friend when he encountered a difficult problem, which highlights the benefits of collaboration in development.
  • Performance Optimization: He addresses performance issues, particularly focusing on the N+1 query problem, and presents strategies to resolve these issues by utilizing Rails features.
  • Exploring New Solutions: Murphy encourages looking for different methods and tools when faced with a coding challenge, illustrating this through his exploration of various gems for performance monitoring and optimization.

Conclusion and Takeaways:

Murphy wraps up by reiterating the significance of search as a development tool, encouraging developers to be strategic and reflective in their searching habits. The main takeaways include:
- Think about why you are searching.
- Use personalized and systematic approaches to search.
- Collaborate with peers for help.
- Explore new tools and solutions regularly.
These strategies not only aid in immediate problem-solving but also enhance overall development practices and learning.

00:00:00.840 Hello, everyone, and welcome to my session.
00:00:12.360 We're going to get started here. I just need to do one thing real quick, so please give me a moment. I'll be right with you.
00:00:24.480 All right! A great start. But look, I search for things all the time, and maybe you do too. Perhaps that's why you are here today.
00:00:34.559 Today, we're going to talk not only about the types of information we search for but also about how to search for them. As we go through this presentation, I want you to think about why you search for the things you do. I believe that understanding the reasons behind your searches can help narrow down your search criteria and assist you in finding faster resolutions.
00:00:57.180 My name is Kevin Murphy, and I'm really thankful that you're here today. I work at a company called BookBub, where we provide ebook recommendations and have an audiobook marketplace as well. By the way, we're hiring, so if you'd like to hear more about that, feel free to come find me later!
00:01:10.560 Today, I'm here to introduce you to a brand-new search engine. I perform searches so often that I decided it was unfair to rely on other people's search engines, so I wrote my own. It's called Alluvial Deposit.
00:01:25.500 Alluvial is unique from a couple of other search engines in a few particular ways. First, if you search for "Kevin Murphy," it's the only search engine where you'll actually find information about me. No other search engine can do that.
00:01:40.020 Second, Alluvial does not provide you with page after page of results. It only gives you three results. If you can't find your answer in three, you probably never needed to know it anyway. Lastly, Alluvial keeps track of your search history across devices and browsers, giving you access to every search you've performed while using it.
00:02:01.920 We'll be iterating on this feature throughout today's presentation. The first thing we will do is add timestamps so you know when you searched for something.
00:02:11.520 In our application, we will use GitHub's View Component library to help manage the presentation of this information. We'll start with a test, specifying the time we want to record for our timestamp.
00:02:24.540 We'll render our component and ensure that the date and time show up formatted as we expect, according to the design specifications.
00:02:37.920 In our view, we'll also use Rails' localized helper, the 'l' method, to format this timestamp as a string. The way this works is by defining formats in your locales file and then specifying how to format the date.
00:02:54.120 At this point, I ran into a problem because my test failed; I initially wanted it to be the actual date and time, but I didn't know the characters to enter into the locales file to format them correctly.
00:03:00.300 I do know that if I search for 'Ruby's DateTime,' I'll come across the documentation, which includes a large table with all the directives that tell me the necessary characters to format the date as desired.
00:03:14.700 After looking at the documentation, I could return to my locales file and fill it with the somewhat cryptic characters that aren't memorized but will help my test pass.
00:03:31.800 That's how I was able to proceed—by searching for the information I needed. While I might not have every detail memorized, knowing to search for 'Ruby's DateTime' helps me find the correct resources without having to memorize those specific characters.
00:03:49.740 This is a good example of how I can free up my brain space for more critical information, such as song lyrics from my middle school days. I need to retain those memories forever!
00:04:07.020 Now, I may not have searched for this using a search engine; perhaps I used a bookmarking tool or note-taking method to keep track of it. Regardless, if I want to retrieve this information later, I need some keywords to trigger that recall. In this case, those keywords are 'Ruby's DateTime.' That's how I remind myself where to go.
00:04:28.560 Next, let's iterate a bit on our component. We'll enhance its appearance. We now have fancy icons on a single line instead of two. We also want to make functional changes. Currently, if we pass 'nil' values to our component, it doesn't handle them well.
00:04:43.800 What we prefer is for it to provide placeholder text indicating that the information is unavailable, rather than causing an error. Fortunately, in our application, we have a Rails helper defined elsewhere to accomplish just that—it wraps the 'l' method to ensure a timestamp is displayed, or else it provides placeholder text.
00:05:00.000 Therefore, we need to update our existing view component to use this Rails helper instead. This should be a straightforward fix; instead of using 'l,' we'll switch to 'l_datetime.' Let's run our tests to ensure everything is working.
00:05:17.760 However, upon testing, we find that it does not work, and we are uncertain as to why, especially since we've utilized both methods in different contexts successfully.
00:05:36.960 A potential approach is to take the error message it produced and search for it directly. I recommend this as it’s often effective. It is unlikely you are the first person to encounter this problem.
00:05:55.140 Yet, here's why I'm hesitant to do that. The exception raised is a 'NoMethodError,' part of Ruby's standard library and rather generic. I've raised this error a few times before in my career, and it's exceedingly common—it won't provide tailored insights for the issue I'm addressing.
00:06:14.220 On the other hand, everything else in this error message is incredibly specific to my application. The 'l_datetime' method is defined in my app's source code, as is the datetime component that is trying (and failing) to call it.
00:06:46.680 If I were to copy this entire error message for my search, I'd likely receive results that don't address my specific issue.
00:07:02.100 Considering the issue arises from integrating a Rails helper into view components, I turned to the README for the View Component for guidance.
00:07:12.360 The README itself is quite terse, but it provides a link to documentation on a separate site, which is extensive and particularly helpful.
00:07:31.680 Since this presentation is about searching, I utilized the search box in the documentation, querying 'helper.' Fortunately, I found a thorough page covering how to access helpers from the view component.
00:07:48.420 After reading through it, I learned about the Helper Proxy it proposed. Now, instead of calling 'l_datetime,' I'll call 'helpers.l_datetime,' and with that minor adjustment, my test will pass. All of this was made possible through diligent searching.
00:08:05.640 Next, we'll implement a new feature to allow comments in our search history. Now users can leave comments about their searches, capturing their thoughts and experiences with the results they found.
00:08:22.200 As we were testing it, we clicked the 'create' button after typing a comment in the comment box and... nothing happened.
00:08:38.880 There was no feedback, no indication whether it was successful or if an error occurred. Our first step was to look at the logs, which confirmed that we issued a request to the controller to add the comment.
00:08:55.920 Upon examining the database, we found that the comment was indeed persisted, but it appears we tried to redirect somewhere else and that part of the process has failed.
00:09:10.560 This application is built on Rails 7 and uses Hotwire. We noted the requests processed as turbo streams, and being unfamiliar with Hotwire, we suspected this might be where we went wrong.
00:09:26.100 So I decided to apply the same search strategy I used earlier. I copied a message from the logs related to Turbo streams and pasted it into my search engine.
00:09:43.380 I omitted the name of the controller because that information is too specific to my application and would likely produce irrelevant results.
00:10:00.840 After my search yielded no useful information, I considered my show page might not be functioning typically. So, I checked by typing the relevant URL directly in the browser, and to my surprise, it rendered correctly.
00:10:14.520 Now, I'm faced with tracing the differences between the Turbo stream requests that failed and the HTML requests that worked.
00:10:31.920 I observed that the HTML request renders a layout, while the Turbo request does not. This led me to suspect that Turbo might not be rendering the layout.
00:10:47.520 Searching for how Turbo renders a layout proved futile as I could not find any relevant information.
00:11:02.640 Next, I turned my attention to the Turbo Rails library's issues list to see if anyone had faced similar problems. Unfortunately, I still came up empty.
00:11:20.760 Frustration began to set in, as I faced capabilities that I have accomplished many times before, and now felt obsolete as if I should relocate to a farm.
00:11:32.280 Realizing the best course of action was to step back, I took a break. I would love to say I went for a run or read a book, but I simply ate a bowl of ice cream.
00:11:50.520 After enjoying my ice cream, I returned to the computer and looked up my search history on Alluvial to see if I’ve missed something.
00:12:05.520 Even still, I felt no closer to solving my issue after taking that break.
00:12:23.280 At this point, I knew I needed a new approach. I reached out to my network, hoping for a little assistance.
00:12:34.560 Thankfully, one of my knowledgeable friends, Connor, promptly pointed out where I went wrong. The problem lay in my attempt to ask Turbo to render my 'show.erb' file.
00:12:52.740 If you are not familiar with Hotwire, it processes HTML over the wire, not ERB. This was my error—it is Hotwire, not 'Yacht wire'. I should have requested to render 'show.html.erb' instead.
00:13:06.060 I learned an important lesson: when troubleshooting, it's crucial to examine the file names and conventions instead of just hastily searching without direction. This may lead you down paths that don't solve the core issue.
00:13:22.260 Consequently, when using search to address direct problems, I highly recommend copying the exact issue you're experiencing to see if others have encountered the same problem.
00:13:40.920 If that yields no results, remember that you don’t always have to consume external sources. Instead, consult the official documentation directly for the best insights.
00:13:59.460 When faced with challenging troubleshooting situations, take a step back. You're not alone—even if you're the only developer on the project.
00:14:15.840 Thanks to Connor, we've successfully added search history comments! Users are now enthusiastically commenting on their searches.
00:14:30.420 However, we did encounter performance issues while loading the search history page, as it struggled to accommodate all those comments.
00:14:45.780 Utilizing Rack Mini Profiler, we discovered that we were executing a database query for each comment rendered on the view, leading to an 'N plus one' query problem.
00:15:04.620 To resolve this, we decided to update our controller to include the associated comments, allowing us to issue a single query to fetch all relevant comments in one go.
00:15:22.740 This optimization successfully solved our performance issue without the need for searching.
00:15:29.040 However, we weren't satisfied with just resolving the issue; we wanted to avoid it in the first place. We remembered a tool called Bullet that can alert us about potential 'N plus one' issues.
00:15:49.020 As we went to add Bullet to our Gemfile, we paused to examine whether there might be alternative solutions.
00:16:04.440 Exploring the realm of 'N plus one' detection, provided me the opportunity to learn about the 'N plus one control' gem and a blog post detailing its features.
00:16:24.960 This gem introduced me to an exciting alternative approach for optimizing query detection and resolution.
00:16:38.640 After researching, I found a new dependent option called 'destroy async' introduced in Rails 6.1 that triggers a background job to delete associated records, rather than executing it in the main request.
00:16:58.620 This revelation intrigued me, as I had never encountered this feature before. It aligned perfectly with our ongoing discussion about optimizing our search history deletion.
00:17:19.680 Incorporating such knowledge allows me to make well-informed decisions about our implementations, based on current best practices.
00:17:38.280 At the beginning of this talk, I asked you to consider why we search for specific things. For me, there are four primary reasons.
00:17:59.520 Firstly, if I've no clue how to do something, I seek wisdom from others. Secondly, I might search for something I already know how to do in search of different approaches.
00:18:05.280 As we are aware, in our industry, practices frequently evolve. Therefore, being mindful of shifts in tools, design patterns, and methodologies can be beneficial.
00:18:21.600 Possessing this understanding may save time later. Lastly, I also search for information to share with others and preserve their knowledge for future reference.
00:18:40.680 In conclusion, visiting kevinjmurphy.com/browser-history offers access to these slides, additional resources, and routes to reach out to me.
00:18:56.280 If you have questions or want to chat, please find me afterwards or during the breaks.
00:19:11.880 If you want to say hello but don't have any questions, consider sharing something you've recently solved at work through searching.
00:19:24.840 We can have a meaningful conversation based on that context.
00:19:34.320 As you continue searching for various topics, I'd encourage you to ponder why you're looking for that information. Taking just a few seconds to strategize on your search can significantly enhance your efficiency.
00:19:45.780 Ultimately, my hope is that you find exactly what you're looking for. Thank you all!