Как я могу поместить (части) большой граф объектов в Rails.cache? - PullRequest
0 голосов
/ 22 ноября 2008

У меня есть класс, в котором поиск экземпляра стоит дорого, поэтому экземпляры кэшируются:

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

Это прекрасно работает, пока Foo s не связали Foo s:

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

Я бы хотел использовать ||= кэширование для сохранения повторных поездок:

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

Но Rails.cache замораживает найденные Foo s, поэтому я не могу установить переменную экземпляра после создания и кэширования объекта. (то есть этот метод поднимает TypeError.)

Одним из решений будет предварительная выборка parent, когда я впервые сделаю дорогую находку, но это может закончиться загрузкой гигантского графа объектов, когда мне нужен только один или два экземпляра. *

1 Ответ

5 голосов
/ 22 ноября 2008

Вы можете использовать ||= кэширование; вам просто нужно использовать небольшую косвенность:

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

Rails.cache не замораживает переменные экземпляра каждого Foo, так что Hash можно изменить!

PS: да, я только что опубликовал этот вопрос и ответ по существу одновременно. Я полагал, что сообщество может извлечь выгоду из моей борьбы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...