缓存是我的视图代码中逻辑最密集的部分,所以我想从一个装饰器中进行片段缓存,但是我不能这样做。
当我这样做的时候,我的装饰师:
def cached_name
h.cache do
"a name here"
end
end我明白了:
当你没有预料到的时候,你就有了一个零目标!您可能会期望数组的一个实例。计算nil.length时发生错误
我从控制器内部实例化我的装饰器。
@presenter = SomePresenter::new我使用HAML作为我的视图。
我怎样才能成功地从我的装潢器里面缓存,这样我的视图就可以做到这样的事情。
= @decorator.cached_logic_heavy_stuff更新:我创建了一个git,显示我的问题:缓存
更新:这可能有效-请参阅回购。
include Haml::Helpers
def another_way_to_try
self.init_haml_helpers
buffer = haml_buffer.buffer
h.with_output_buffer(buffer) do
h.cache do
h.concat "i should still not be empty"
end
end
end发布于 2012-09-22 15:27:21
Rails的cache方法试图根据被调用的视图推断缓存键。由于您实际上不是从视图中调用它(而是从装饰类的实例中调用它),所以我希望它在试图构建缓存键时会爆炸。
您可以尝试通过h.cache "your cache key" do显式地传递缓存密钥。有了完整的堆栈跟踪,您就可以知道它在哪里抛出异常,然后也可以解决这个问题。但是,如果没有完整的堆栈跟踪,就很难帮助您。
编辑:查看Rails缓存代码,我认为这可能是一个更深层次的问题;它试图获取output_buffer的长度,它将在视图上下文之外(即在Draper中)不可用。您可以尝试添加:
def output_buffer
h.output_buffer
end但如果不进行测试,我想如果没有更多的工作,它可能无法完全按照计划工作。这只是一个粗略的猜测-如果这是问题,我会感到惊讶,但希望它能让你走上正确的道路。
资料来源中的说明如下:
# VIEW TODO: Make #capture usable outside of ERB
# This dance is needed because Builder can't use capture这表明这不是一个完全解决的问题,因此您可能需要在Rails内部进行一些调查才能使这个问题正常工作。
发布于 2013-08-08 14:16:03
我建议直接使用Rails.cache可以解决您的问题;我们在Rails 4的装饰器中也是这样做的。
def cached_name
Rails.cache.fetch(source) do
source.name # etc.
end
end发布于 2012-09-22 15:05:06
如果您使用Draper,我相信您不需要显式传递视图上下文。您可能希望在实例化时将模型或集合传递给draper present。示例:
class UserDecorator < Draper::Base
decorates :user
# additional methods
end
# in the controller
@presenter = UserDecorator.new(@user) # for an instance
@presenter = UserDecorator.decorate(@users) # for a collection我怀疑您得到的零对象错误来自于代码中没有列出的另一个方法调用。
至于您的装饰器中的片段缓存,您需要使用concat助手方法让它在装饰器中工作:
# your decorator class
def cached_name
h.cache("some_cache_key") do
h.concat "a name here"
end
endhttps://stackoverflow.com/questions/12437597
复制相似问题