【发布时间】:2017-07-20 07:47:18
【问题描述】:
我正在使用 Rails 5.0.1,并且对以下问题感到非常困惑。我很少有具有多态关联的模型。
class Container < ApplicationRecord
has_many :steps, as: 'parent', dependent: :destroy
end
class Step < ApplicationRecord
belongs_to :parent, polymorphic: true
belongs_to :implementation, polymorphic: true
end
class FirstStep < ApplicationRecord
has_one :step, as: 'implementation'
has_many :params, dependent: :destroy
end
class SecondStep < ApplicationRecord
has_one :step, as: 'implementation'
has_many :headers, dependent: :destroy
end
class Param < ApplicationRecord
belongs_to :first_step
end
class Header < ApplicationRecord
belongs_to :second_step
end
步骤与实现相关联(FirstStep、SecondStep)。除此之外,container 也可以是step 的实现。我正在使用Active Model Serializers 将模型信息序列化为 JSON。以下是序列化器的相关代码。
class StepSerializer < ActiveModel::Serializer
attributes :id, :implementation_type, :implementation_id, :active, :position
belongs_to :implementation
end
class FirstStepSerializer < ActiveModel::Serializer
attributes :name, :params_attributes
def params_attributes
object.params.map { |p| ParamSerializer.new(p).attributes }
end
end
class SecondStepSerializer < ActiveModel::Serializer
attributes :id, :title, :headers_attributes
def headers_attributes
object.headers.map { |p| HeaderSerializer.new(p).attributes }
end
end
class ParamSerializer < ActiveModel::Serializer
attributes :id
end
class HeaderSerializer < ActiveModel::Serializer
attributes :id
end
step 模型的实现可以具有不同的属性,如模型中所指定。问题是,当我写的时候
render json: container.steps
它会触发 N+1 个查询以获取结果。如何优化?
编辑 1
受this answer 的启发,我尝试通过implementation_type 来分隔对象,并且成功了。我所做的是:
# my controller action
def index
steps = []
steps += container.steps.where(implementation_type: 'FirstStep').includes(implementation: [:params])
steps += container.steps.where(implementation_type: 'SecondStep').includes(implementation: [:headers])
render json: steps
end
这阻止了 N+1 个查询以获取 params 和 headers,但如果 step 是 container,则它不起作用。
【问题讨论】:
标签: ruby-on-rails polymorphic-associations active-model-serializers