ruby-on-rails - 如何在 active_model_serializers 中执行预先加载

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

我有一个具有多层嵌套关联的模型。例如,

ModelA has_many: model_b
ModelB has_one : model_c
ModelC has_many: model_d
ModelD has_many: model_e
  ...

在序列化器中,embed :ids, include: true 用于侧面加载:

class ModelASerializer < ActiveModel::Serializer
    embed :ids, include: true

    has_many: model_b

    attributes: ...
end

class ModelBSerializer < ActiveModel::Serializer
    embed :ids, include: true
    ...

当 model_a 被渲染时,它有一个严重的“n+1 问题”,并且会生成数千个调用,例如:

    ModelC Load (0.3ms)  SELECT "model_cs".* FROM "model_cs" WHERE "model_cs"."id" = $1 LIMIT 1  [["id", "2060c506-8c9c-4d1c-a64c-62455fa18bc4"]]
    CACHE (0.0ms)  SELECT "model_ds".* FROM "model_ds" WHERE "model_ds"."id" = $1 LIMIT 1  [["id", "2e36f19f-25e1-4953-99ba-f8c0271106dd"]]
    CACHE (0.0ms)  SELECT "model_es".* FROM "model_es" WHERE "model_es"."id" = $1 LIMIT 1  [["id", "31e53b55-6df6-44cd-98ad-2011cced1e1a"]]

即使明确指定了包含内容,它似乎也没有效果:

render json: ModelA.includes(:model_bs => [:model_c =>[:model_ds => [:model_es]]])

active_model_serializers 文档说您应该使用预先加载,但没有指定他们打算如何完成它。是否必须在序列化器中指定包含内容?如果是这样,怎么办?

最佳答案

这是一个很好的描述和解释。这就是您要找的东西?

class ModelName
  default_scope includes(:other)
end

How to add `:include` to default_scope?

编辑:

我没有像您那样在一堆模型中完成此操作,我已经使用序列化器通过一个级别完成了此操作,并且我还使用 jbuilder 来减轻痛苦并通过 2 个级别利用控制。我仍然相信您希望将这一层控制放在模型级别。

关于ruby-on-rails - 如何在 active_model_serializers 中执行预先加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23814678/

相关文章:

ruby-on-rails - Rails 事件模型序列化程序,如何返回空字符串而不是 null

ruby-on-rails - ActiveModel Serializer - 将参数传递给序列化器

ruby-on-rails - ActiveModel::Serializer:如何从分层 Rails 模型中收集验证错误?

ruby-on-rails - 自定义设计 Cookie

ruby-on-rails - 如何防止 Rails `exists?` 调用 `after_find`?

ruby-on-rails - 如何覆盖 rails 模型中的 class_method 问题

ruby-on-rails - 如何在 attr_encrypted 中搜索加密字段

css - 如何为rails 3中的每个页面编写css

ruby-on-rails - rails 、 cucumber 、 capybara : session is not persisted

ruby-on-rails - Rails 是否每次在生产中点击它时都会重新编译整个 erb/haml View ?