DEV Community

Andy Huynh
Andy Huynh

Posted on • Edited on

memoization

You've seen it before: ||=.

This is Ruby's way of caching data. Take the contrived example below that involves zero caching.

class Account
  ...

  private

  def retrieve_credit_card
    if purchasing_account.present?
      purchasing_account.credit_card
    end
  end

  def purchasing_account
    Account.find(id)
  end
end
Enter fullscreen mode Exit fullscreen mode

Here's why this sucks: we hit the database twice. When invoking #retrieve_credit_card, we ask for the account twice. This gets expensive on the database and a bad thing working in larger codebases with lots of data.

Cache the Account#find query like so.

class Account
  def retrieve_credit_card
    if purchasing_account.present?
      purchasing_account.credit_card
    end
  end

  private

  def purchasing_account
    @purchasing_account ||= Account.find(id)
  end
end
Enter fullscreen mode Exit fullscreen mode

This implementation is more efficient. When asking if a purchasing_account is present.. that's the first hit to the database. However, this time we ask that same instance (our cached version) for the its credit card. This saves us a roundtrip to the database. Optimization for the win!

Also, this is an actual example of a commit by yours truly. I was digging through my old pull requests and discovered I wrote this commit at work. Embarrassing to say the least, but it's fun to point fingers at your younger, simple minded self. Get cachin', ya'll.

Top comments (0)