Я следовал общему решению Никласа Хофера, но обнаружил, что его реализация не соответствует точной семантике хелпера Rails-кеша. А именно, он пытался вернуть кэшированный HTML-код от помощника, а не записывать его в буфер, используя safe_concat
, что и делает помощник Rails.
Использование помощника Rails выглядит следующим образом:
- cache do
= something
В то время как его решение требовало следующего синтаксиса:
= cache_with_updated_csrf do
= something
Для согласованности я бы предпочел, чтобы они работали одинаково. Поэтому я использовал этот синтаксис:
- cache_form do
= something
Вот моя реализация. Он также пропускает кэширование, когда кэширование отключено, как это делает помощник Rails.
module CacheHelper
# Cache a form with a fresh CSRF
def cache_form(name = {}, options = nil, &block)
if controller.perform_caching
fragment = fragment_for(name, options, &block)
fragment_with_fresh_csrf = Nokogiri::HTML::DocumentFragment.parse( fragment ).tap do |doc|
doc.css("input[name=#{request_forgery_protection_token}]").each { |e| e['value'] = form_authenticity_token }
end.to_html
safe_concat fragment_with_fresh_csrf
else
yield
end
nil
end
end