ruby-on-rails - 如何缓存对象的 JSON 表示?

标签 ruby-on-rails json caching

JSON我的 Car 的代表模型,我包括一个昂贵的方法的输出:

#car.rb
def as_json(options={})
  super(options.merge(methods: [:some_expensive_method]))
end

我有一个标准的索引操作:
#cars_controller.rb
respond_to :json
def index
  respond_with(Car.all)
end

我也用 JSON其他地方的汽车表示,如下所示:
#user_feed.rb
def feed_contents
  Horse.all + Car.all
end

#user_feeds_controller.rb
respond_to :json
def index
  respond_with(UserFeed.feed_contents)
end

因为JSON car 的表示在多个地方使用,我希望它自己缓存,使用 car.cache_key作为自动过期的缓存键。

这就是我目前的做法:
#car.rb
def as_json(options={})
  Rails.cache.fetch("#{cache_key}/as_json") do
    super(options.merge(methods: [:some_expensive_method]))
  end
end

将缓存代码放入 as_json但不正确,因为缓存不是 as_json 的一部分的责任。这样做的正确方法是什么?我正在使用 Rails 3.2.15。

最佳答案

首先让我说我为这个问题的努力鼓掌。你会发现很难找到比我更对以正确的方式设计软件感兴趣的人——包括用小方法在一个抽象层次上做好一件事——。

但是,我不得不说,在这一点上,我实际上反对问题的前提。我想你的 as_json最好的方式就是这样。

最重要的是将客户端与实现分离。唯一的客户Car#as_json需要知道的是,返回值是一个 Car 的 JSON 表示.和 as_json做那件事并且做得很好。缓存和/或获取是应该保留在方法内部的实现细节,它是该任务不可或缺的细节。

否则就像用 if 说任何方法一样陈述是“不正确的”,因为它做了两件事。当然这不是真的。在这两种情况下(使用 if 和使用 Rails.cache.fetch ),方法实现是一些原子操作,其结果基于条件。

那是可以通过两种方式之一进行的一件事,这与两件事不同。

同时,我不得不不同意@severin 的回应。它当然会起作用,但是您现在已经将您的 View 与实现细节相结合。没有什么,当然不是你的观点,应该对缓存的方法有任何想法,甚至涉及缓存。在我看来,您现在已经泄露了这种方法的抽象。也许这无关紧要,但既然我们在谈论做事的“正确方法”......

所以我说保持现状。但我相信这是一个很好的问题。

关于ruby-on-rails - 如何缓存对象的 JSON 表示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19914120/

相关文章:

caching - 多个实例时 Azure 上的图形渲染问题

ruby-on-rails - 在多个 Controller 中使用相同的 `before_action` 过滤器

java - 通过 AppEngine 访问 Books API 失败,错误代码为 400

java - 如何在 eclipselink 中禁用缓存

c# - 利用 IIS 中的浏览器缓存(谷歌页面速度问题)

javascript - 使用javascript将base64字符串转换为图像

ruby-on-rails - 我应该如何仅向事件设备发送推送通知?

ruby-on-rails - Ruby on Rails - 检查提交的表单数据是否与数据库数据匹配

ruby-on-rails - 工厂女孩中非事件记录协会的问题

json - Wordpress API JSON 返回限制