{"id":878,"date":"2026-01-30T09:55:28","date_gmt":"2026-01-30T09:55:28","guid":{"rendered":"https:\/\/productive.io\/engineering\/?p=878"},"modified":"2026-01-30T09:55:28","modified_gmt":"2026-01-30T09:55:28","slug":"watch-out-when-overriding-memoized-methods","status":"publish","type":"post","link":"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/","title":{"rendered":"Watch Out When Overriding Memoized Methods"},"content":{"rendered":"<p   > <a href='https:\/\/productive.io\/engineering\/category\/backend\/'>Backend<\/a><\/p> &#8211; <p   > {{minutes}} min read<\/p> <h1   > Watch Out When Overriding Memoized Methods<\/h1> <a href=\"https:\/\/productive.io\/engineering\/author\/nikola-buhincek\/\"> <img  src=\"https:\/\/website-assets.productive.io\/uploads\/2024\/02\/profi-e1708437204597.jpeg\"  alt=\"\" loading=lazy \/> <\/a> <a href=\"https:\/\/productive.io\/engineering\/author\/nikola-buhincek\/\"> <p   > Nikola Buhini\u010dek<\/p><\/a> Backend Tech Lead at Productive. Pretty passionate about working on one product and taking part in decision-making. When I\u2019m not coding, you\u2019ll probably find me chilling with my friends and family.<p   > January 30, 2026<\/p> <a aria-hidden=\"false\"   href=https:\/\/www.facebook.com\/sharer.php?u=https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods target=_blank rel=\"noopener noreferrer\" > <\/a><a aria-hidden=\"false\"   href=https:\/\/twitter.com\/intent\/tweet?text=Watch%20Out%20When%20Overriding%20Memoized%20Methods&amp;url=https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods target=_blank rel=\"noopener noreferrer\" > <\/a><a aria-hidden=\"false\"   href=https:\/\/www.linkedin.com\/shareArticle?mini=true&amp;url=https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods target=_blank rel=\"noopener noreferrer\" > <\/a> <img  src=\"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/BLOG_2x.png\"  alt=\"\" loading=lazy \/> <p   > <\/p> <p   > This post was inspired by a bug that was caused by not thinking ahead when overriding a memoized method. Once we noticed the buggy behaviour, it took me some\u00a0<em>binding.pry<\/em>\u00a0time to figure out what was going on.<br><br>Lets check out what happened.<\/p> <img  src=\"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/Screenshot-2024-01-19-at-10.51.21.png\"  alt=\"\" loading=lazy \/> <p   > A simple\u00a0<strong>Ruby<\/strong>\u00a0class which is the base class for the specific actions we need to implement for our\u00a0<strong>Rails app<\/strong>.<br><br>The action for which we figured out the bug was the action of creating comments on various objects. This is what the code looks like:<\/p> <img  src=\"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/Screenshot-2024-01-19-at-10.53.28.png\"  alt=\"\" loading=lazy \/> <p   > Not much code is actually shown but just enough to spot the bug. Found it?<\/p> <h2   > <strong>What Was Going On?<\/strong><\/h2> <p   > Basically what was happening when running\u00a0<code>CreateComment#execute_action<\/code>\u00a0was the following:<br><br>In the\u00a0<code>execute_action<\/code>\u00a0we firstly need to interpolate some attributes &#8211; defined by the specific action class. In this case, for the\u00a0<code>CreateComment<\/code>\u00a0action that was only the\u00a0<code>'body'<\/code>\u00a0attribute.<\/p> <img  src=\"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/Screenshot-2024-01-19-at-10.58.48.png\"  alt=\"\" loading=lazy \/> <p   > That&#8217;s fine &#8211; we do some logic, the\u00a0<code>'body'<\/code>\u00a0attribute gets interpolated and that value is set as the new value for the\u00a0<code>'body'<\/code>\u00a0key in the form_attributes hash.<\/p> <img  src=\"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/Screenshot-2024-01-19-at-10.59.18.png\"  alt=\"\" loading=lazy \/> <p   > But, as the implementation of the\u00a0<code>CreateComment<\/code>\u00a0class uses\u00a0<code>super.merge(...)<\/code>\u00a0what we get is actually a new hash each time the method is called.<\/p> <img  src=\"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/Screenshot-2024-01-19-at-10.59.33.png\"  alt=\"\" loading=lazy \/> <p   > The next time, after the interpolation is over, the method\u00a0<code>form_attributes<\/code>\u00a0is called when passing that hash to our form object and in that moment, the form object gets a newly generated hash that doesn&#8217;t have the interpolated\u00a0<code>'body'<\/code>\u00a0value. So the interpolation was actually pointless as would any other modification of the\u00a0<code>form_attributes<\/code>\u00a0hash prior to the\u00a0<code>form.process<\/code>\u00a0call be.<\/p> <h2   > <strong>The Solution<\/strong><\/h2> <img  src=\"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/Screenshot-2024-01-19-at-13.08.54.png\"  alt=\"\" loading=lazy \/> <p   > Added memoization to the\u00a0<code>CreateComment#form_attributes<\/code>\u00a0method.<br><br>Simple as that and when you think about it, also pretty obvious that it needed to look like this from the start.<br><br><em>p.s. These snippets maybe look a bit too simple and memoization probably looks like it&#8217;s not needed but it&#8217;s a stripped version of the real classes. The\u00a0<code>form_attributes<\/code>\u00a0method is called and modified quite a few times<\/em>.<\/p> <a aria-hidden=\"false\"   href=https:\/\/www.facebook.com\/sharer.php?u=https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods target=_blank rel=\"noopener noreferrer\" > <\/a><a aria-hidden=\"false\"   href=https:\/\/twitter.com\/intent\/tweet?text=Watch%20Out%20When%20Overriding%20Memoized%20Methods&amp;url=https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods target=_blank rel=\"noopener noreferrer\" > <\/a><a aria-hidden=\"false\"   href=https:\/\/www.linkedin.com\/shareArticle?mini=true&amp;url=https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods target=_blank rel=\"noopener noreferrer\" > <\/a> <img  src=\"https:\/\/website-assets.productive.io\/uploads\/2024\/02\/profi-e1708437204597.jpeg\"  alt=\"\" loading=lazy \/> <p   > Nikola Buhini\u010dek<\/p> Backend Tech Lead at Productive. Pretty passionate about working on one product and taking part in decision-making. When I\u2019m not coding, you\u2019ll probably find me chilling with my friends and family.<a   href=\"https:\/\/productive.io\/engineering\/author\/nikola-buhincek\/\" > More From This Author <\/a> <h2   > Related articles<\/h2> <a href=\"https:\/\/productive.io\/engineering\/custom-fields-give-your-customers-the-fields-they-need\/\"   > <img  src=\"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2022\/11\/Asset_11-768x322.png\"  alt=\"\" loading=lazy \/> <p   > Backend \u2022 Engineering<\/p> <h2   > Custom Fields: Give Your Customers the Fields They Need<\/h2> <\/a><a href=\"https:\/\/productive.io\/engineering\/a-close-call-with-real-time-how-rethinking-pub-sub-saved-the-day\/\"   > <img  src=\"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/BP@2x-768x322.png\"  alt=\"\" loading=lazy \/> <p   > Backend \u2022 Testing<\/p> <h2   > A Close Call with Real-Time: How Rethinking Pub-Sub Saved the Day<\/h2> <\/a> <h2   > Related jobs<\/h2> <a href=\"https:\/\/productive.io\/careers\/open-job-application\/\"  > <p  > Open Job Application<\/p><p  > <\/p> <\/a>","protected":false},"excerpt":{"rendered":"","protected":false},"author":40,"featured_media":891,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"es_utils_meta_schema":"","footnotes":""},"categories":[11],"tags":[],"class_list":["post-878","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-backend"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.2) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Watch Out When Overriding Memoized Methods - Building Productive<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Watch Out When Overriding Memoized Methods\" \/>\n<meta property=\"og:url\" content=\"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/\" \/>\n<meta property=\"og:site_name\" content=\"Building Productive\" \/>\n<meta property=\"article:published_time\" content=\"2026-01-30T09:55:28+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/BLOG_2x.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1901\" \/>\n\t<meta property=\"og:image:height\" content=\"797\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Nikola Buhini\u010dek\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Nikola Buhini\u010dek\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/\"},\"author\":{\"name\":\"Nikola Buhini\u010dek\",\"@id\":\"https:\/\/productive.io\/engineering\/#\/schema\/person\/b8aea92d17640ade1fc1230b0812ae29\"},\"headline\":\"Watch Out When Overriding Memoized Methods\",\"datePublished\":\"2026-01-30T09:55:28+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/\"},\"wordCount\":6,\"commentCount\":0,\"image\":{\"@id\":\"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/BLOG_2x.png\",\"articleSection\":[\"Backend\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/\",\"url\":\"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/\",\"name\":\"Watch Out When Overriding Memoized Methods - Building Productive\",\"isPartOf\":{\"@id\":\"https:\/\/productive.io\/engineering\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/BLOG_2x.png\",\"datePublished\":\"2026-01-30T09:55:28+00:00\",\"author\":{\"@id\":\"https:\/\/productive.io\/engineering\/#\/schema\/person\/b8aea92d17640ade1fc1230b0812ae29\"},\"breadcrumb\":{\"@id\":\"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/#primaryimage\",\"url\":\"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/BLOG_2x.png\",\"contentUrl\":\"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/BLOG_2x.png\",\"width\":1901,\"height\":797},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/productive.io\/engineering\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Watch Out When Overriding Memoized Methods\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/productive.io\/engineering\/#website\",\"url\":\"https:\/\/productive.io\/engineering\/\",\"name\":\"Building Productive\",\"description\":\"Just another Productive Sites site\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/productive.io\/engineering\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/productive.io\/engineering\/#\/schema\/person\/b8aea92d17640ade1fc1230b0812ae29\",\"name\":\"Nikola Buhini\u010dek\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/2687fe62ebca4b36f13407f15bc76ff55d23d54ec9f86877ececbfc80ada7b6e?s=96&d=mm&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/2687fe62ebca4b36f13407f15bc76ff55d23d54ec9f86877ececbfc80ada7b6e?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/2687fe62ebca4b36f13407f15bc76ff55d23d54ec9f86877ececbfc80ada7b6e?s=96&d=mm&r=g\",\"caption\":\"Nikola Buhini\u010dek\"},\"url\":\"https:\/\/productive.io\/engineering\/author\/nikola-buhincek\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Watch Out When Overriding Memoized Methods - Building Productive","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/","og_locale":"en_US","og_type":"article","og_title":"Watch Out When Overriding Memoized Methods","og_url":"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/","og_site_name":"Building Productive","article_published_time":"2026-01-30T09:55:28+00:00","og_image":[{"width":1901,"height":797,"url":"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/BLOG_2x.png","type":"image\/png"}],"author":"Nikola Buhini\u010dek","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Nikola Buhini\u010dek","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/#article","isPartOf":{"@id":"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/"},"author":{"name":"Nikola Buhini\u010dek","@id":"https:\/\/productive.io\/engineering\/#\/schema\/person\/b8aea92d17640ade1fc1230b0812ae29"},"headline":"Watch Out When Overriding Memoized Methods","datePublished":"2026-01-30T09:55:28+00:00","mainEntityOfPage":{"@id":"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/"},"wordCount":6,"commentCount":0,"image":{"@id":"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/#primaryimage"},"thumbnailUrl":"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/BLOG_2x.png","articleSection":["Backend"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/","url":"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/","name":"Watch Out When Overriding Memoized Methods - Building Productive","isPartOf":{"@id":"https:\/\/productive.io\/engineering\/#website"},"primaryImageOfPage":{"@id":"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/#primaryimage"},"image":{"@id":"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/#primaryimage"},"thumbnailUrl":"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/BLOG_2x.png","datePublished":"2026-01-30T09:55:28+00:00","author":{"@id":"https:\/\/productive.io\/engineering\/#\/schema\/person\/b8aea92d17640ade1fc1230b0812ae29"},"breadcrumb":{"@id":"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/#primaryimage","url":"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/BLOG_2x.png","contentUrl":"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/BLOG_2x.png","width":1901,"height":797},{"@type":"BreadcrumbList","@id":"https:\/\/productive.io\/engineering\/watch-out-when-overriding-memoized-methods\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/productive.io\/engineering\/"},{"@type":"ListItem","position":2,"name":"Watch Out When Overriding Memoized Methods"}]},{"@type":"WebSite","@id":"https:\/\/productive.io\/engineering\/#website","url":"https:\/\/productive.io\/engineering\/","name":"Building Productive","description":"Just another Productive Sites site","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/productive.io\/engineering\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/productive.io\/engineering\/#\/schema\/person\/b8aea92d17640ade1fc1230b0812ae29","name":"Nikola Buhini\u010dek","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/2687fe62ebca4b36f13407f15bc76ff55d23d54ec9f86877ececbfc80ada7b6e?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/2687fe62ebca4b36f13407f15bc76ff55d23d54ec9f86877ececbfc80ada7b6e?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/2687fe62ebca4b36f13407f15bc76ff55d23d54ec9f86877ececbfc80ada7b6e?s=96&d=mm&r=g","caption":"Nikola Buhini\u010dek"},"url":"https:\/\/productive.io\/engineering\/author\/nikola-buhincek\/"}]}},"featured_image":"https:\/\/website-assets.productive.io\/uploads\/sites\/2\/2024\/01\/BLOG_2x.png","category":"Backend","_links":{"self":[{"href":"https:\/\/productive.io\/engineering\/wp-json\/wp\/v2\/posts\/878","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/productive.io\/engineering\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/productive.io\/engineering\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/productive.io\/engineering\/wp-json\/wp\/v2\/users\/40"}],"replies":[{"embeddable":true,"href":"https:\/\/productive.io\/engineering\/wp-json\/wp\/v2\/comments?post=878"}],"version-history":[{"count":5,"href":"https:\/\/productive.io\/engineering\/wp-json\/wp\/v2\/posts\/878\/revisions"}],"predecessor-version":[{"id":919,"href":"https:\/\/productive.io\/engineering\/wp-json\/wp\/v2\/posts\/878\/revisions\/919"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/productive.io\/engineering\/wp-json\/wp\/v2\/media\/891"}],"wp:attachment":[{"href":"https:\/\/productive.io\/engineering\/wp-json\/wp\/v2\/media?parent=878"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/productive.io\/engineering\/wp-json\/wp\/v2\/categories?post=878"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/productive.io\/engineering\/wp-json\/wp\/v2\/tags?post=878"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}