Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 活动模型序列化程序10缓存。它似乎不起作用。为什么?_Ruby On Rails_Api_Active Model Serializers - Fatal编程技术网

Ruby on rails 活动模型序列化程序10缓存。它似乎不起作用。为什么?

Ruby on rails 活动模型序列化程序10缓存。它似乎不起作用。为什么?,ruby-on-rails,api,active-model-serializers,Ruby On Rails,Api,Active Model Serializers,我的玩具应用程序有两个模型、出租单元和用户。你可以找到回购协议 我正在运行Rails 5和AMS 10 active_model_serializers (0.10.0.rc4) ... rails (5.0.0.beta3) actioncable (= 5.0.0.beta3) actionmailer (= 5.0.0.beta3) actionpack (= 5.0.0.beta3) ... 我有一个RentalUnitSerializer,如下所示

我的玩具应用程序有两个模型、出租单元和用户。你可以找到回购协议

我正在运行Rails 5和AMS 10

active_model_serializers (0.10.0.rc4)
...
rails (5.0.0.beta3)
      actioncable (= 5.0.0.beta3)
      actionmailer (= 5.0.0.beta3)
      actionpack (= 5.0.0.beta3)
...
我有一个RentalUnitSerializer,如下所示:

class RentalUnitSerializer < ActiveModel::Serializer
  cache key: 'rental_unit', expires_in: 3.hours
  attributes :id, :rooms, :bathrooms, :price, :price_cents

  belongs_to :user
end
这就是奇怪的行为

当我访问时,这是我的日志,没有缓存的迹象:

Started GET "/users" for ::1 at 2016-03-04 15:18:12 -0500
Processing by UsersController#index as HTML
  User Load (0.1ms)  SELECT "users".* FROM "users"
[active_model_serializers]   RentalUnit Load (0.2ms)  SELECT "rental_units".* FROM "rental_units" WHERE "rental_units"."user_id" = ?  [["user_id", 1]]
[active_model_serializers]   RentalUnit Load (0.1ms)  SELECT "rental_units".* FROM "rental_units" WHERE "rental_units"."user_id" = ?  [["user_id", 2]]
[active_model_serializers]   RentalUnit Load (0.1ms)  SELECT "rental_units".* FROM "rental_units" WHERE "rental_units"."user_id" = ?  [["user_id", 3]]
[active_model_serializers] Rendered ActiveModel::Serializer::CollectionSerializer with ActiveModel::Serializer::Adapter::JsonApi (11.0ms)
Completed 200 OK in 13ms (Views: 12.5ms | ActiveRecord: 0.5ms)
当我访问时,是否有一些缓存

Started GET "/rental_units" for ::1 at 2016-03-04 15:18:37 -0500
Processing by RentalUnitsController#index as HTML
  RentalUnit Load (0.4ms)  SELECT "rental_units".* FROM "rental_units"
[active_model_serializers]   User Load (0.9ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
[active_model_serializers]   CACHE (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
[active_model_serializers]   CACHE (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
[active_model_serializers]   User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 2], ["LIMIT", 1]]
[active_model_serializers] Rendered ActiveModel::Serializer::CollectionSerializer with ActiveModel::Serializer::Adapter::JsonApi (16.1ms)
Completed 200 OK in 21ms (Views: 19.1ms | ActiveRecord: 1.4ms)
发生了什么事?在后面的日志中,用户是否正在被缓存?我相信,由于3个不同的出租单元属于用户1,AMS有一些默认的缓存,相同的SQL查询只是命中某种缓存。因此,对User1的第一个查询会访问服务器的数据库,但对User1的后续查询不会。这个缓存在哪里?它在服务器上吗?还是一些网络服务器


但我认为我的序列化程序中的缓存策略根本不起作用。为什么?

要帮助调试,请尝试为缓存设置记录器。Rails缓存支持设置记录器,但默认情况下MemoryStore不设置记录器

在初始值设定项中,尝试以下操作:

# config/initializers/cache.rb
Rails.cache.logger = Logger.new(STDOUT)
# or Rails.cache.logger = Rails.logger
重新启动Rails服务器,您将看到缓存命中/未命中的日志记录。我怀疑它在起作用,但可能不是你所期望的那样

既然你问了,实际上你的问题涉及到了两层缓存:片段或视图缓存和查询缓存

您已经启用了缓存as:memory\u store,它将创建一个ActiveSupport::cache::MemoryStore的实例,该实例在应用程序中和Rails控制台中都可以作为Rails.cache访问

您还为序列化程序设置了缓存选项。从您的版本的列表中,看起来您已正确设置了此选项。到目前为止还不错

通常,在Rails控制器中,只有在渲染视图时才会调用Rails缓存。在您的例子中,您正在通过AMS呈现json视图;对于HTML模板也可以这样做

第一次发出此请求时,缓存处于冷态,执行DB查询,Rails使用一个或多个缓存键向缓存请求JSON字符串的表示。由于这组资源的缓存是空的,因此必须生成JSON字符串,然后将其缓存在Rails.cache中,然后返回响应

下一次在到期窗口内发出此请求时,将进行DB查询-Rails需要知道哪些资源需要请求缓存,对吗这一次,缓存命中,字符串从缓存返回。不需要生成新的JSON。请注意,这仍然会导致DB命中以请求原始资源。AMS需要这些请求来查找JSON的缓存键

您还将看到缓存选择。。。日志中的查询。正如在另一个答案中提到的,这可能表明您正在反复进行相同的DB查询,这通常是一个错误的指示,因此建议立即加载这些关系。您的RentalUnit属于:user,因此对于每个租赁单元,都会为每个用户发出单独的请求-您可以在一个查询中抓取所有这些用户,并立即加载


Rails提供了一些功能。这与我们讨论过的为AMS启用的视图缓存是分开的。

我尝试了上述所有答案,但均无效。最后,我在项目的根目录中使用了rm-rf./tmp/cache

Started GET "/users" for ::1 at 2016-03-04 15:18:12 -0500
Processing by UsersController#index as HTML
  User Load (0.1ms)  SELECT "users".* FROM "users"
[active_model_serializers]   RentalUnit Load (0.2ms)  SELECT "rental_units".* FROM "rental_units" WHERE "rental_units"."user_id" = ?  [["user_id", 1]]
[active_model_serializers]   RentalUnit Load (0.1ms)  SELECT "rental_units".* FROM "rental_units" WHERE "rental_units"."user_id" = ?  [["user_id", 2]]
[active_model_serializers]   RentalUnit Load (0.1ms)  SELECT "rental_units".* FROM "rental_units" WHERE "rental_units"."user_id" = ?  [["user_id", 3]]
[active_model_serializers] Rendered ActiveModel::Serializer::CollectionSerializer with ActiveModel::Serializer::Adapter::JsonApi (11.0ms)
Completed 200 OK in 13ms (Views: 12.5ms | ActiveRecord: 0.5ms)
Started GET "/rental_units" for ::1 at 2016-03-04 15:18:37 -0500
Processing by RentalUnitsController#index as HTML
  RentalUnit Load (0.4ms)  SELECT "rental_units".* FROM "rental_units"
[active_model_serializers]   User Load (0.9ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
[active_model_serializers]   CACHE (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
[active_model_serializers]   CACHE (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
[active_model_serializers]   User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 2], ["LIMIT", 1]]
[active_model_serializers] Rendered ActiveModel::Serializer::CollectionSerializer with ActiveModel::Serializer::Adapter::JsonApi (16.1ms)
Completed 200 OK in 21ms (Views: 19.1ms | ActiveRecord: 1.4ms)
# config/initializers/cache.rb
Rails.cache.logger = Logger.new(STDOUT)
# or Rails.cache.logger = Rails.logger