17

バックグラウンド

関連付けが深くネストされた Rails アプリケーションがあります。

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

-<  (has many)

私はActive Model Serializerを使用して API を構築しています。

クライアント側では、タイムカードとそのすべての関連付けを一度にロードしたいと考えています。

現在、私のシリアライザーは次のようになっています。

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 ...

問題

これはすべて機能しますが、熱心に読み込まれるものは何もありません。そのため、リクエストごとにデータベースに対して多くの呼び出しを行うことになります。週ごとに、その週の日について個別のリクエストを作成します。そして、毎日、work_periods、小計、および調整に対して個別のリクエストを行います。

4

2 に答える 2

13

weeks解決策の 1 つは、TimecardSerializer で独自のメソッドを定義することです。そこから.includes()、熱心にロードしたいすべての関連付けを行うことができます。

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

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

すべてのクエリは引き続きログに表示されますが、ほとんどは実際のクエリではなく、キャッシュされたクエリになります。

于 2013-08-08T19:38:17.243 に答える
9

同様の問題がありました。コントローラーで修正しました。シリアライザーに入れるというアイデアは気に入っていますが、コントローラーに入れると、ArraySerializer によって作成された n+1 週間の問題もキャッチされます。

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

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

これで、熱心な読み込みを行い、クエリを 6 つのデータベース ヒットに制限する必要があります。

于 2013-08-20T13:00:32.683 に答える