【问题标题】:Active Model Serializer caching of calculated field计算字段的活动模型序列化程序缓存
【发布时间】:2016-12-10 21:26:48
【问题描述】:

我正在尝试缓存一组项目,这是我的 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 时,我得到了相同的时间,并且没有缓存。

我配置错了什么?

【问题讨论】:

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


    【解决方案1】:

    你能做到吗?

    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 时包含协议类别和组。您执行的查询过多。

    【讨论】:

    • 感谢您的回复,当我写:def num_of_protocols object.protocol_categories.count end 我仍然得到多个查询部分。我怎么能吃到这个?
    • 如何为整个集合配置缓存?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多