Eager load associations with Active Model Serializers

泪湿孤枕 提交于 2019-12-18 11:27:17

问题


Background

I have a rails application with deeply nested associations.

                          .-< WorkPeriod
Timecard -< Week -< Day -<--< Subtotal
                          `-< Adjustment

-<  (has many)

I'm using Active Model Serializer to build out the API.

On the client side I want to load a timecard and all it's associations in one shot.

Currently my serializers look like this,

class TimecardSerializer < ActiveModel::Serializer
  embed :ids, include: true
  has_many :weeks
end
class WeekSerializer < ActiveModel::Serializer
  embed :ids, include: true
  has_many :days
end
# ... etc ...

Problem

This all works find, except nothing gets eager-loaded. So it ends up making lots of calls to the database for each request. For each week, it makes a separate request for the days in that week. And for each day, it makes a separate request for it's work_periods, subtotals, and adjustments.


回答1:


One solution is to define your own weeks method on the TimecardSerializer. From there you can .includes() all the associations you want to eager load.

class TimecardSerializer < ActiveModel::Serializer
  embed :ids, include: true
  has_many :weeks

  def weeks
    object.weeks.includes(days: [:sub_totals, :work_periods, :adjustments])
  end
end

All the queries will still show up in the log but most will be a cached query instead of a real one.




回答2:


I had a similar issue. I fixed it in my controller. I like the idea of putting it in the serializer, but having it in the controller catches the n+1 weeks problem created by the ArraySerializer too.

Timecard.find(params[:id]).includes(weeks: [{ days: [:sub_totals, :work_periods, :adjustments] }])

and

Timecard.includes(weeks: [{ days: [:sub_totals, :work_periods, :adjustments] }])

should now eager load and limit the query to just six db hits.



来源:https://stackoverflow.com/questions/18134649/eager-load-associations-with-active-model-serializers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!