0

次のような has_many 関係があります。

class Event < ActiveRecord::Base 
    has_many :event_rows
    ...
end
class EventRow < ActiveRecord::Base
    belongs_to :event
    ...
end

以下のスニペットを実行すると、36 個のクエリが表示されます。

@events = Event.where("date = ?", @date).all
@events.each do |e|
    first = e.event_rows.first
    first.event
end

このスニペットを実行すると、19 個のクエリしか取得できません

@events = Event.where("date = ?", @date).all
@events.each do |e|
    first = e.event_rows.first
    first.event = e # forcing the parent
    first.event
end

私は何か間違ったことをしていますか、またはレールは EventRow がイベントを要求するたびにクエリを実行しますか?

コメントへの対応: クエリは CACHED としてマークされていません:

SQL (0.7ms)[0m  SELECT "event_rows"."id" AS t0_r0, "event_rows"."event_id" ... WHERE "event_rows"."event_id" = 1 LIMIT 1
Event Load (0.6ms)[0m  [1mSELECT "events".* FROM "events" WHERE "events"."id" = 1 LIMIT 1[0m
SQL (3.2ms)[0m  SELECT "event_rows"."id" AS t0_r0, "event_rows"."event_id" ... WHERE "event_rows"."event_id" = 2 LIMIT 1
Event Load (0.5ms)[0m  [1mSELECT "events".* FROM "events" WHERE "events"."id" = 2 LIMIT 1[0m
4

2 に答える 2

1

質問の答えにたどり着きました。

inverse_ofオプションを使用して同じインスタンスを保持できるようです。

:inverse_of がなければ、m と f.man は同じオブジェクトの異なるインスタンスになります (f.man がデータベースから再び引き出されます)。これらの新しい :inverse_of オプションを使用すると、m と f.man はメモリ インスタンスで同じになります。

于 2013-08-27T21:29:31.407 に答える
0

Michael Szyndel に同意しました。開発中はモデルのキャッシュが無効になっている可能性があります。また、次のようにコードを更新したいと考えています。

@events = Event.includes(:event_rows).where(date: @date)
@events.each do |e|
    # your code
end

ここで重要なのは、 event_rowsallの熱心な読み込みを行うインクルードです。

それが役立つことを願っています..

于 2013-07-12T20:00:19.687 に答える