首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法从装饰器缓存(draper)

无法从装饰器缓存(draper)
EN

Stack Overflow用户
提问于 2012-09-15 13:02:09
回答 4查看 1.3K关注 0票数 1

缓存是我的视图代码中逻辑最密集的部分,所以我想从一个装饰器中进行片段缓存,但是我不能这样做。

当我这样做的时候,我的装饰师:

代码语言:javascript
复制
def cached_name
  h.cache do
   "a name here"
  end
end

我明白了:

当你没有预料到的时候,你就有了一个零目标!您可能会期望数组的一个实例。计算nil.length时发生错误

我从控制器内部实例化我的装饰器。

代码语言:javascript
复制
@presenter = SomePresenter::new

我使用HAML作为我的视图。

我怎样才能成功地从我的装潢器里面缓存,这样我的视图就可以做到这样的事情。

代码语言:javascript
复制
= @decorator.cached_logic_heavy_stuff

更新:我创建了一个git,显示我的问题:缓存

更新:这可能有效-请参阅回购。

代码语言:javascript
复制
  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
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-09-22 15:27:21

Rails的cache方法试图根据被调用的视图推断缓存键。由于您实际上不是从视图中调用它(而是从装饰类的实例中调用它),所以我希望它在试图构建缓存键时会爆炸。

您可以尝试通过h.cache "your cache key" do显式地传递缓存密钥。有了完整的堆栈跟踪,您就可以知道它在哪里抛出异常,然后也可以解决这个问题。但是,如果没有完整的堆栈跟踪,就很难帮助您。

编辑:查看Rails缓存代码,我认为这可能是一个更深层次的问题;它试图获取output_buffer的长度,它将在视图上下文之外(即在Draper中)不可用。您可以尝试添加:

代码语言:javascript
复制
def output_buffer
  h.output_buffer
end

但如果不进行测试,我想如果没有更多的工作,它可能无法完全按照计划工作。这只是一个粗略的猜测-如果这是问题,我会感到惊讶,但希望它能让你走上正确的道路。

资料来源中的说明如下:

代码语言:javascript
复制
# VIEW TODO: Make #capture usable outside of ERB
# This dance is needed because Builder can't use capture

这表明这不是一个完全解决的问题,因此您可能需要在Rails内部进行一些调查才能使这个问题正常工作。

票数 0
EN

Stack Overflow用户

发布于 2013-08-08 14:16:03

我建议直接使用Rails.cache可以解决您的问题;我们在Rails 4的装饰器中也是这样做的。

代码语言:javascript
复制
def cached_name
  Rails.cache.fetch(source) do
    source.name # etc.
  end
end
票数 2
EN

Stack Overflow用户

发布于 2012-09-22 15:05:06

如果您使用Draper,我相信您不需要显式传递视图上下文。您可能希望在实例化时将模型或集合传递给draper present。示例:

代码语言:javascript
复制
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助手方法让它在装饰器中工作:

代码语言:javascript
复制
# your decorator class
def cached_name
  h.cache("some_cache_key") do
    h.concat "a name here"
  end
end
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12437597

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档