Skip to content

Commit 637bb72

Browse files
author
David Heinemeier Hansson
committed
Digestor should just rely on the finder to know about the format and the variant -- trying to pass it back in makes a mess of things (oh, and doesnt work)
1 parent 4bca347 commit 637bb72

File tree

3 files changed

+39
-83
lines changed

3 files changed

+39
-83
lines changed

actionview/lib/action_view/digestor.rb

Lines changed: 29 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,13 @@ class << self
1212
# Supported options:
1313
#
1414
# * <tt>name</tt> - Template name
15-
# * <tt>format</tt> - Template format
16-
# * <tt>variant</tt> - Variant of +format+ (optional)
1715
# * <tt>finder</tt> - An instance of ActionView::LookupContext
1816
# * <tt>dependencies</tt> - An array of dependent views
1917
# * <tt>partial</tt> - Specifies whether the template is a partial
20-
def digest(options_or_deprecated_name, *deprecated_args)
21-
options = _options_for_digest(options_or_deprecated_name, *deprecated_args)
18+
def digest(options)
19+
options.assert_valid_keys(:name, :finder, :dependencies, :partial)
2220

23-
details_key = options[:finder].details_key.hash
24-
dependencies = Array.wrap(options[:dependencies])
25-
cache_key = ([options[:name], details_key, options[:format], options[:variant]].compact + dependencies).join('.')
21+
cache_key = ([ options[:name], options[:finder].details_key.hash ].compact + Array.wrap(options[:dependencies])).join('.')
2622

2723
# this is a correctly done double-checked locking idiom
2824
# (ThreadSafe::Cache's lookups have volatile semantics)
@@ -33,63 +29,41 @@ def digest(options_or_deprecated_name, *deprecated_args)
3329
end
3430
end
3531

36-
def _options_for_digest(options_or_deprecated_name, *deprecated_args)
37-
if !options_or_deprecated_name.is_a?(Hash)
38-
ActiveSupport::Deprecation.warn \
39-
'ActionView::Digestor.digest changed its method signature from ' \
40-
'#digest(name, format, finder, options) to #digest(options), ' \
41-
'with options now including :name, :format, :finder, and ' \
42-
':variant. Please update your code to pass a Hash argument. ' \
43-
'Support for the old method signature will be removed in Rails 5.0.'
44-
45-
_options_for_digest(deprecated_args[2] || {}).merge \
46-
name: options_or_deprecated_name,
47-
format: deprecated_args[0],
48-
finder: deprecated_args[1]
49-
else
50-
options_or_deprecated_name.assert_valid_keys(:name, :format, :variant, :finder, :dependencies, :partial)
51-
options_or_deprecated_name
52-
end
53-
end
54-
5532
private
33+
def compute_and_store_digest(cache_key, options) # called under @@digest_monitor lock
34+
klass = if options[:partial] || options[:name].include?("/_")
35+
# Prevent re-entry or else recursive templates will blow the stack.
36+
# There is no need to worry about other threads seeing the +false+ value,
37+
# as they will then have to wait for this thread to let go of the @@digest_monitor lock.
38+
pre_stored = @@cache.put_if_absent(cache_key, false).nil? # put_if_absent returns nil on insertion
39+
PartialDigestor
40+
else
41+
Digestor
42+
end
5643

57-
def compute_and_store_digest(cache_key, options) # called under @@digest_monitor lock
58-
klass = if options[:partial] || options[:name].include?("/_")
59-
# Prevent re-entry or else recursive templates will blow the stack.
60-
# There is no need to worry about other threads seeing the +false+ value,
61-
# as they will then have to wait for this thread to let go of the @@digest_monitor lock.
62-
pre_stored = @@cache.put_if_absent(cache_key, false).nil? # put_if_absent returns nil on insertion
63-
PartialDigestor
64-
else
65-
Digestor
44+
digest = klass.new(options).digest
45+
# Store the actual digest if config.cache_template_loading is true
46+
@@cache[cache_key] = stored_digest = digest if ActionView::Resolver.caching?
47+
digest
48+
ensure
49+
# something went wrong or ActionView::Resolver.caching? is false, make sure not to corrupt the @@cache
50+
@@cache.delete_pair(cache_key, false) if pre_stored && !stored_digest
6651
end
67-
68-
digest = klass.new(options).digest
69-
# Store the actual digest if config.cache_template_loading is true
70-
@@cache[cache_key] = stored_digest = digest if ActionView::Resolver.caching?
71-
digest
72-
ensure
73-
# something went wrong or ActionView::Resolver.caching? is false, make sure not to corrupt the @@cache
74-
@@cache.delete_pair(cache_key, false) if pre_stored && !stored_digest
75-
end
7652
end
7753

78-
attr_reader :name, :format, :variant, :path, :finder, :options
54+
attr_reader :name, :finder, :options
7955

80-
def initialize(options_or_deprecated_name, *deprecated_args)
81-
options = self.class._options_for_digest(options_or_deprecated_name, *deprecated_args)
82-
@options = options.except(:name, :format, :variant, :finder)
83-
@name, @format, @variant, @finder = options.values_at(:name, :format, :variant, :finder)
84-
@path = "#{@name}.#{format}".tap { |path| path << "+#{@variant}" if @variant }
56+
def initialize(options)
57+
@name, @finder = options.values_at(:name, :finder)
58+
@options = options.except(:name, :finder)
8559
end
8660

8761
def digest
8862
Digest::MD5.hexdigest("#{source}-#{dependency_digest}").tap do |digest|
89-
logger.try :info, "Cache digest for #{path}: #{digest}"
63+
logger.try :info, " Cache digest for #{template.inspect}: #{digest}"
9064
end
9165
rescue ActionView::MissingTemplate
92-
logger.try :error, "Couldn't find template for digesting: #{path}"
66+
logger.try :error, " Couldn't find template for digesting: #{name}"
9367
''
9468
end
9569

@@ -101,13 +75,12 @@ def dependencies
10175

10276
def nested_dependencies
10377
dependencies.collect do |dependency|
104-
dependencies = PartialDigestor.new(name: dependency, format: format, variant: variant, finder: finder).nested_dependencies
78+
dependencies = PartialDigestor.new(name: dependency, finder: finder).nested_dependencies
10579
dependencies.any? ? { dependency => dependencies } : dependency
10680
end
10781
end
10882

10983
private
110-
11184
def logger
11285
ActionView::Base.logger
11386
end
@@ -121,11 +94,7 @@ def partial?
12194
end
12295

12396
def template
124-
@template ||= begin
125-
finder.disable_cache do
126-
finder.find(logical_name, [], partial?, [], formats: [format], variants: [variant])
127-
end
128-
end
97+
@template ||= finder.disable_cache { finder.find(logical_name, [], partial?) }
12998
end
13099

131100
def source
@@ -134,7 +103,7 @@ def source
134103

135104
def dependency_digest
136105
template_digests = dependencies.collect do |template_name|
137-
Digestor.digest(name: template_name, format: format, variant: variant, finder: finder, partial: true)
106+
Digestor.digest(name: template_name, finder: finder, partial: true)
138107
end
139108

140109
(template_digests + injected_dependencies).join("-")

actionview/lib/action_view/helpers/cache_helper.rb

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -165,20 +165,10 @@ def cache_fragment_name(name = {}, options = nil)
165165

166166
def fragment_name_with_digest(name) #:nodoc:
167167
if @virtual_path
168-
variant = request.variant.is_a?(Array) ? request.variant.first : request.variant
168+
names = Array(name.is_a?(Hash) ? controller.url_for(name).split("://").last : name)
169+
digest = Digestor.digest name: @virtual_path, finder: lookup_context, dependencies: view_cache_dependencies
169170

170-
options = {
171-
name: @virtual_path,
172-
format: formats.last.to_sym,
173-
variant: variant,
174-
finder: lookup_context,
175-
dependencies: view_cache_dependencies
176-
}
177-
178-
names = Array(name.is_a?(Hash) ? controller.url_for(name).split("://").last : name)
179-
digest = Digestor.digest(options)
180-
181-
[*names, digest]
171+
[ *names, digest ]
182172
else
183173
name
184174
end

actionview/test/template/digestor_test.rb

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,13 @@ def test_directory_depth_dependency
100100
end
101101

102102
def test_logging_of_missing_template
103-
assert_logged "Couldn't find template for digesting: messages/something_missing.html" do
103+
assert_logged "Couldn't find template for digesting: messages/something_missing" do
104104
digest("messages/show")
105105
end
106106
end
107107

108108
def test_logging_of_missing_template_ending_with_number
109-
assert_logged "Couldn't find template for digesting: messages/something_missing_1.html" do
109+
assert_logged "Couldn't find template for digesting: messages/something_missing_1" do
110110
digest("messages/show")
111111
end
112112
end
@@ -207,7 +207,7 @@ def test_old_style_hash_in_render_invocation
207207
end
208208

209209
def test_variants
210-
assert_digest_difference("messages/new", false, variant: :iphone) do
210+
assert_digest_difference("messages/new", false, variants: [:iphone]) do
211211
change_template("messages/new", :iphone)
212212
change_template("messages/_header", :iphone)
213213
end
@@ -261,10 +261,6 @@ def test_digest_cache_cleanup_with_recursion_and_template_caching_off
261261
ActionView::Resolver.caching = resolver_before
262262
end
263263

264-
def test_arguments_deprecation
265-
assert_deprecated(/will be removed/) { ActionView::Digestor.digest('messages/show', :html, finder) }
266-
assert_deprecated(/will be removed/) { ActionView::Digestor.new('messages/show', :html, finder) }
267-
end
268264

269265
private
270266
def assert_logged(message)
@@ -294,10 +290,11 @@ def assert_digest_difference(template_name, persistent = false, options = {})
294290

295291
def digest(template_name, options = {})
296292
options = options.dup
297-
finder.formats = [:html]
298-
finder.variants = [options[:variant]] if options[:variant].present?
299293

300-
ActionView::Digestor.digest({ name: template_name, format: :html, finder: finder }.merge(options))
294+
finder.formats = [:html]
295+
finder.variants = options.delete(:variants) || []
296+
297+
ActionView::Digestor.digest({ name: template_name, finder: finder }.merge(options))
301298
end
302299

303300
def finder

0 commit comments

Comments
 (0)