How can I put (parts of) a large object graph in Rails.cache?

I have a class where finding an instance is expensive, so the instances are cached:

class Foo
  def self.find(id)
    Rails.cache.fetch("Foo.#{id}") do
      // some expensive lookup, like an HTTParty request, or a long SQL query
      ...
    end
  end
end

      

This works fine until s are Foo

linked Foo

:

class Foo
  def children
    @child_foo_ids.map { |id| Foo.find(id) }
  end
end

      

I would like to use caching ||=

to preserve repeated disconnections:

class Foo
  def children
    @children ||= @child_foo_ids.map { |id| Foo.find(id) }
  end
end

      

But it Rails.cache

freezes the Foo

s found , so I can't set the instance variable after the object is created and cached. (i.e. this method calls a TypeError

.)

One solution is to prefetch parent

when I make a costly find first, but that can cause the gigantic graphic to load when I only need one or two instances.

0


source to share


1 answer


You can use caching ||=

; you just need to touch a little:

class Foo
  def initialize
    @related_objects = {}
  end
  def children
    @related_objects[:children] ||= @child_foo_ids.map { |id| Foo.find(id) }
  end
end

      



Rails.cache

will not freeze instance variables for each Foo

, so that Hash

can be changed!

PS: yes, I just posed this question and answer at almost the same time. I figured the community could benefit from my struggle.

+5


source







All Articles