0
我正在使用Rails 5.0.1,並對以下問題感到困惑。我很少有多態關聯的模型。Rails觸發多態關聯的N + 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
這是行不通的。
這仍然觸發N + 1個查詢,因爲'object.implementation'的'params'和'headers'無法加載預先。 – 31piy