Есть ли в Rails теги для истечения срока действия кэша? - PullRequest
3 голосов
/ 14 апреля 2011

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

Кэши представления одна основная модель , но мы использовали данные из 5 других моделей (не связанных ассоциацией) внутри этого основного кэша.Ускорение фрагмента с помощью уборщика в основной модели легко, но эти дополнительные модели также изменяются, и необходимо, чтобы срок действия этой страницы истек.

Мы не можем использовать маршрут regexp для удаления ключей кэша, потому что мыдолжны ссылаться на эту запись кэша только основной моделью - другие модели определяются дорогим запросом, который мы выполняем внутри блока кэша в контроллере.

Есть ли у Rails 3 способ по существу использовать теги , чтобы пометить запись в кэше, чтобы мы могли удалить ее, когда какая-либо из 6 моделей на странице изменится, но мы все равно можем найти запись в кэше только из ключа основной модели?


Вот некоторый фиктивный код для выражения идеи:

В контроллере

@cache_key = "/page/#{params[:name]}/#{params[:id]}"
unless fragment_exist? ( { :slug => @cache_key })
  # run our processes here that will be needed in the view, 
  # then cache the data that is used outside the view
  Rails.cache.write(@cache_key, { (data goes here) } )
  # run our expensive query here:
  @similar_pages = Page.pricey_query!.limit(5).all
else 
  cached = Rails.cache.read(@cache_key)
end

В представлении

- cache( {:slug => @cache_key} ) do
 - @similar_pages.each do |page|
  = image_tag page.photos.first.image.url
  -# more pretty stuff here

Моя цель:

  • Я:"О, страница @cache_key изменилась, истекаем!"
  • Rails: Okay, easy!
  • Me:"Одна из похожих страниц чанged их первое фото, что я делаю? "
  • Rails: Umm... #(*$^*@ .. does ... not ... compute.

Ответы [ 3 ]

2 голосов
/ 21 апреля 2011

Как сказал Тадман в комментариях к вопросу, мне пришлось изобрести собственное решение, так как Rails технически не допускает теги в том смысле, в котором они мне нужны.Вот обобщенное решение для тех, кто заинтересован в том, чтобы сделать нечто подобное:

Я создал новую таблицу с именем SimilarPages:

create_table :similar_pages, {:id => false} do |t|
  t.integer :page_id, :similar_page_id
  # you could also do `t.string :tag_name` or similar
end
add_index :similar_pages, :page_id
add_index :similar_pages, :similar_page_id

Технически, я мог бы сделать самореферентные отношения has_manyна Pages, но я решил не делать этого, поскольку мне никогда не нужно ссылаться на него таким образом.Я только что создал простую SimilarPage модель:

class SimilarPage < ActiveRecord::Base
  belongs_to :page
  belongs_to :similar_page, :class_name => 'Page'
end

Затем, используя ar-extensions (потому что я ленивый, а также потому, что я хотел сделать это в одном операторе INSERT), я делаю это вблок кеша:

SimilarPage.delete_all("page_id = '#{@page_id}'")
SimilarPage.import [:page_id, :similar_page_id], @similar_pages.collect {|s| SimilarPage.new(:page_id=>@page_id,:similar_page_id=>s.id)}

В моем expire_cache_for методе моего Обозревателя я делаю это:

SimilarPage.where(:similar_page_id => expiring_page.id).all.each do |s|
  ActionController::Base.new.expire_fragment(/page_show__#{s.page_id}__.*/) 
  # the regexp is for different currencies being cached ^
  Rails.cache.delete("page_show_#{s.page_id}")
end
0 голосов
/ 20 февраля 2013

Касса может быть полезна. «Кэширование на основе тегов»

# in your view
cache @some_record, :tag => 'some-component'

# later
Cashier.expire 'some-component'

https://github.com/twinturbo/cashier

0 голосов
/ 18 апреля 2011

В этом видео есть отличное объяснение того, как Rails генерирует теги для истечения срока действия контента. http://railslab.newrelic.com/2009/02/19/episode-8-memcached

Если коротко, если вы передадите весь объект в кеш, он сгенерирует ключ кеша, которыйиспользует метку времени, которая будет обновляться при изменении объекта.

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