提交 40f79da8 编写于 作者: K Kasper Timm Hansen

Make digest cache work in development.

Avoid computing the same fragment digest many times when looping over templates.

The cache is cleared on every request so template changes are still picked up.
上级 57ab74cd
......@@ -8,6 +8,13 @@ class Digestor
@@cache = ThreadSafe::Cache.new
@@digest_monitor = Monitor.new
class PerRequestDigestCacheExpiry < Struct.new(:app) # :nodoc:
def call(env)
ActionView::Digestor.cache.clear
app.call(env)
end
end
class << self
# Supported options:
#
......@@ -41,10 +48,7 @@ def compute_and_store_digest(cache_key, options) # called under @@digest_monitor
Digestor
end
digest = klass.new(options).digest
# Store the actual digest if config.cache_template_loading is true
@@cache[cache_key] = stored_digest = digest if ActionView::Resolver.caching?
digest
@@cache[cache_key] = stored_digest = klass.new(options).digest
ensure
# something went wrong or ActionView::Resolver.caching? is false, make sure not to corrupt the @@cache
@@cache.delete_pair(cache_key, false) if pre_stored && !stored_digest
......
......@@ -42,6 +42,14 @@ class Railtie < Rails::Railtie # :nodoc:
end
end
initializer "action_view.per_request_digest_cache" do |app|
ActiveSupport.on_load(:action_view) do
if app.config.consider_all_requests_local
app.middleware.use ActionView::Digestor::PerRequestDigestCacheExpiry
end
end
end
initializer "action_view.setup_action_pack" do |app|
ActiveSupport.on_load(:action_controller) do
ActionView::RoutingUrlFor.include(ActionDispatch::Routing::UrlFor)
......
......@@ -239,16 +239,6 @@ def test_dependencies_via_options_results_in_different_digest
assert_not_equal digest_phone, digest_fridge_phone
end
def test_cache_template_loading
resolver_before = ActionView::Resolver.caching
ActionView::Resolver.caching = false
assert_digest_difference("messages/edit", true) do
change_template("comments/_comment")
end
ensure
ActionView::Resolver.caching = resolver_before
end
def test_digest_cache_cleanup_with_recursion
first_digest = digest("level/_recursion")
second_digest = digest("level/_recursion")
......
require 'isolation/abstract_unit'
require 'rack/test'
require 'minitest/mock'
require 'action_view'
require 'active_support/testing/method_call_assertions'
class PerRequestDigestCacheTest < ActiveSupport::TestCase
include ActiveSupport::Testing::Isolation
include ActiveSupport::Testing::MethodCallAssertions
include Rack::Test::Methods
setup do
build_app
add_to_config 'config.consider_all_requests_local = true'
app_file 'app/models/customer.rb', <<-RUBY
class Customer < Struct.new(:name, :id)
extend ActiveModel::Naming
include ActiveModel::Conversion
end
RUBY
app_file 'config/routes.rb', <<-RUBY
Rails.application.routes.draw do
resources :customers, only: :index
end
RUBY
app_file 'app/controllers/customers_controller.rb', <<-RUBY
class CustomersController < ApplicationController
def index
render [ Customer.new('david', 1), Customer.new('dingus', 2) ]
end
end
RUBY
app_file 'app/views/customers/_customer.html.erb', <<-RUBY
<% cache customer do %>
<%= customer.name %>
<% end %>
RUBY
require "#{app_path}/config/environment"
end
teardown :teardown_app
test "digests are reused when rendering the same template twice" do
get '/customers'
assert_equal 200, last_response.status
assert_equal [ '8ba099b7749542fe765ff34a6824d548' ], ActionView::Digestor.cache.values
assert_equal %w(david dingus), last_response.body.split.map(&:strip)
end
test "template digests are cleared before a request" do
assert_called(ActionView::Digestor.cache, :clear) do
get '/customers'
assert_equal 200, last_response.status
end
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册