活动模型序列化器缓存计算字段

时间:2016-08-04 16:24:22

标签: ruby-on-rails ruby-on-rails-4 caching active-model-serializers

我试图缓存一组项目,这是我的AMS:

class ApplicationCategorySerializer < ActiveModel::Serializer

  cache({})
  cache key: 'application_category', expires_in: 3.days

  attributes :id
  attributes :name
  attributes :active
  attributes :group
  attributes :num_of_protocols

  belongs_to :group do |serializer|
    serializer.attributes[:group][:name]
  end


  def num_of_protocols
    ApplicationCategory.find(object.id).protocol_categories.count
  end
end

我的问题是,如果没有:num_of_protocols部分,生成响应的速度要快10倍,

当我查看日志时,我可以看到:

Started GET "/application_categories.json" for 127.0.0.1 at 2016-08-04 19:12:27 +0300
Processing by ApplicationCategoriesController#index as JSON
  ApplicationCategory Load (3.0ms)  SELECT "application_categories".* FROM "application_categories"
[active_model_serializers]   Group Load (1.0ms)  SELECT  "groups".* FROM "groups" WHERE "groups"."id" = ? LIMIT 1  [["id", 2066]]
[active_model_serializers]   ApplicationCategory Load (0.0ms)  SELECT  "application_categories".* FROM "application_categories" WHERE "application_categories"."id" = ? LIMIT 1  [["id", 1]]
[active_model_serializers]    (0.0ms)  SELECT COUNT(*) FROM "protocol_categories" INNER JOIN "application_categories_protocol_categories" ON "protocol_categories"."id" = "application_categories_protocol_categories"."protocol_category_id" WHERE "application_categories_protocol_categories"."application_category_id" = ?  [["application_category_id", 1]]
[active_model_serializers]   CACHE (0.0ms)  SELECT  "groups".* FROM "groups" WHERE "groups"."id" = ? LIMIT 1  [["id", 2066]]
[active_model_serializers]   ApplicationCategory Load (0.0ms)  SELECT  "application_categories".* FROM "application_categories" WHERE "application_categories"."id" = ? LIMIT 1  [["id", 2]]
[active_model_serializers]    (0.0ms)  SELECT COUNT(*) FROM "protocol_categories" INNER JOIN "application_categories_protocol_categories" ON "protocol_categories"."id" = "application_categories_protocol_categories"."protocol_category_id" WHERE "application_categories_protocol_categories"."application_category_id" = ?  [["application_category_id", 2]]
[active_model_serializers]   CACHE (0.0ms)  SELECT  "groups".* FROM "groups" WHERE "groups"."id" = ? LIMIT 1  [["id", 2066]]
...................... [many many more lines like those...]
[active_model_serializers]   CACHE (0.0ms)  SELECT  "application_categories".* FROM "application_categories" WHERE "application_categories"."id" = ? LIMIT 1  [["id", 608]]
[active_model_serializers]   CACHE (0.0ms)  SELECT COUNT(*) FROM "protocol_categories" INNER JOIN "application_categories_protocol_categories" ON "protocol_categories"."id" = "application_categories_protocol_categories"."protocol_category_id" WHERE "application_categories_protocol_categories"."application_category_id" = ?  [["application_category_id", 608]]
[active_model_serializers]   CACHE (0.0ms)  SELECT  "application_categories".* FROM "application_categories" WHERE "application_categories"."id" = ? LIMIT 1  [["id", 609]]
[active_model_serializers]   CACHE (0.0ms)  SELECT COUNT(*) FROM "protocol_categories" INNER JOIN "application_categories_protocol_categories" ON "protocol_categories"."id" = "application_categories_protocol_categories"."protocol_category_id" WHERE "application_categories_protocol_categories"."application_category_id" = ?  [["application_category_id", 609]]
[active_model_serializers]   CACHE (0.0ms)  SELECT  "application_categories".* FROM "application_categories" WHERE "application_categories"."id" = ? LIMIT 1  [["id", 610]]
[active_model_serializers]   CACHE (0.0ms)  SELECT COUNT(*) FROM "protocol_categories" INNER JOIN "application_categories_protocol_categories" ON "protocol_categories"."id" = "application_categories_protocol_categories"."protocol_category_id" WHERE "application_categories_protocol_categories"."application_category_id" = ?  [["application_category_id", 610]]
[active_model_serializers] Rendered ActiveModel::Serializer::CollectionSerializer with ActiveModelSerializers::Adapter::Attributes (1521.15ms)

如何通过缓存获得更好的结果? - 当我评论cache行时,我得到了aprox。与他们相同的时间,当我删除:num_of_protocols时我与&amp;同时没有缓存。

我配置错误了什么?

1 个答案:

答案 0 :(得分:0)

你能这样做吗?

def num_of_protocols
  object.protocol_categories.count
end

而且,对于我来说,序列化器已经有一段时间了,但我认为你能够做到这一点......

def num_of_protocols
  protocol_categories.count
end

这是更好的ruby(在protocal_categories已经作为数组加载的情况下)

def num_of_protocols
  protocol_categories.size
end

并且,如果所有这些都有效,请确保在渲染到json之前实例化@application_category时包含protocol_categories和groups。你的查询太多了。