Некоторые поля получают старые значения в кеше фрагментов в Rails
У меня есть представление, чтобы показать подробную информацию о ресурсе, который сохраняется в базе данных. Некоторые детали принадлежат самой модели ресурсов, а некоторые детали относятся к связанным моделям.
В представлении я использую кеширование фрагмента для деталей.
Когда пользователь нажимает кнопку в представлении, часть представления заменяется формой, поэтому пользователь может редактировать данные без загрузки новой страницы. Когда форма открыта, срок действия кеша истекает (на самом деле, я проверил). Когда пользователь отправляет форму (using :remote => true
), форма скрыта, а исходный контент перезагружается с помощью jQuery и визуализируется частично.
Пока все работает просто отлично. Исходный контент корректно загружается с новыми значениями из кода внутри <% cache ... do %>
а также <% end %>
,
Странно то, что когда я перезагружаю страницу, некоторые новые значения исчезают. Вместо этого отображаются некоторые старые значения (те, которые должны были быть кэшированы после последней отправки). И еще более странно то, что некоторые значения обновляются, даже если они находятся в том же новом файле кэша, что и неправильные значения.
Насколько я вижу, значения в связанных моделях верны, а значения в модели ресурсов неверны (старые). Я задавался вопросом, было ли это как-то связано с кэшированием SQL, но я не думаю, что это так, потому что я думаю, что кэш SQL должен быть очищен при перезагрузке страницы.
Если я открою форму и отправлю снова, данные будут обновлены, и все в порядке. То есть данные из последней отправки поступают в кеш. Если я изменю данные в форме перед отправкой, это все еще данные из последней отправки, которые включены в кеш-файл. Таким образом, кажется, что данные, представленные для модели ресурсов, задерживаются на одну отправку, даже если другие поля обновлены правильно.
Если я отключу кеширование в development.rb, все будет работать как положено. Все данные обновляются каждый раз.
У меня, кстати, такая же проблема на моем сервере.
У кого-нибудь есть подсказка?
2 ответа
Похоже, что данные немного кэшируются вскоре после их обновления. Мое решение пока состоит в том, чтобы отказаться от кэширования в представлении, если с момента обновления ресурса прошло менее двух минут. Фрагмент не кэшируется, пока кто-то не обновит страницу чуть позже. Это не очень хорошее решение, в то время как каждый ресурс (30 ресурсов) на странице должен запрашивать время обновления при каждом просмотре страницы.
Не уверен, поможет ли это, но в последние пару дней я реализовал схему фрагментирования кеша на своем собственном сайте с некоторым успехом.
Я реализовал функцию get_cache_key во всех моих моделях
def get_cache_key(prefix=nil)
cache_key = []
cache_key << prefix if prefix
cache_key << self
child_objects.in_sort_order.each do |child_object|
cache_key << child_object.get_cache_key
end
return cache_key.flatten
end
В моих взглядах я тогда использовал
<% cache(@home_page.get_cache_key('some_name_for_fragment')) do %>
...Render View
<% end %>
Модели теперь создают ключ кеша, который сделает недействительным кеш, если родительская модель или любой из ее дочерних элементов будут изменены.
Полное описание здесь, на моем сайте. Стратегия кеширования в Rails с использованием подхода на основе ключей