我有一个相当简单的空对象类:
class NullObject
def present?
false
end
end
class NullVal < NullObject
attr_accessor :field
delegate(
:allow_edits,
:box,
:content,
:id,
:locked_for?,
:number,
:page_num,
:page_seq,
:position_css,
:position_css_hash,
:required,
:required?,
:size_css,
:size_css_hash,
:type,
to: :field,
)
def initialize(field:)
self.field = field
end
end
我在rails部分缓存密钥中使用它:
- cache [vals] do
-# render stuff
我看到以下错误:
NoMethodError - undefined method `cache_key' for #<NullVal:0x000000080ceb78>:
/home/fletch/.rvm/rubies/ruby-2.1.6/lib/ruby/2.1.0/delegate.rb:343:in `block in delegating_block'
activesupport (4.2.2) lib/active_support/cache.rb:94:in `retrieve_cache_key'
activesupport (4.2.2) lib/active_support/cache.rb:95:in `block in retrieve_cache_key'
activesupport (4.2.2) lib/active_support/cache.rb:95:in `retrieve_cache_key'
activesupport (4.2.2) lib/active_support/cache.rb:95:in `block in retrieve_cache_key'
activesupport (4.2.2) lib/active_support/cache.rb:95:in `retrieve_cache_key'
activesupport (4.2.2) lib/active_support/cache.rb:87:in `expand_cache_key'
actionpack (4.2.2) lib/action_controller/caching/fragments.rb:22:in `fragment_cache_key'
actionpack (4.2.2) lib/action_controller/caching/fragments.rb:43:in `read_fragment'
actionview (4.2.2) lib/action_view/helpers/cache_helper.rb:183:in `read_fragment_for'
actionview (4.2.2) lib/action_view/helpers/cache_helper.rb:179:in `fragment_for'
actionview (4.2.2) lib/action_view/helpers/cache_helper.rb:115:in `cache'
app/views/docs/_doc.html.haml:13:in `block in _app_views_docs__doc_html_haml___3057171325955977412_79957620'
activesupport
的相关代码行是:
when key.respond_to?(:cache_key) then key.cache_key
如果我在其中放置puts
,则会为true
返回key.respond_to?(:cache_key)
,实际上它是NullVal
的实例。如果我在控制台中实例化NullVal
,它会返回false
。这里发生了什么? method(:respond_to?).source_location
为{...}返回nil
。
答案 0 :(得分:1)
好的,找出问题所在。我有一个ValDecorator
类用于包装NullVal
。当我将它打印到控制台时,它显示为#<NullVal:0x0000000a1f3ab0 @field=...>
,但它实际上是装饰器。我正在使用DelegateClass
:
class ValDecorator < DelegateClass(Val)
end
由于Val
使用respond_to?
并且实际上试图在NullVal
上调用它,因此会引发一个令人惊讶的错误。将不得不考虑更多的实施。