6

アプリケーションに親子関係があります

class Polling
 has_many :alerts, :dependent => :destroy

class Alert
 belongs_to :polling

アラートのインデックス ページで、各親からのデータを表示する必要があります。これにより、2 つのクエリが発生します。

Alert Load (6.1ms)  SELECT * FROM (SELECT * FROM "ALERTS" INNER JOIN "POLLINGS" ON "POLLINGS"."ID" = "ALERTS"."POLLING_ID" ORDER BY "ALERTS"."ID" DESC) WHERE ROWNUM <= 1
Polling Load (1.8ms)  SELECT "POLLINGS".* FROM "POLLINGS" WHERE "POLLINGS"."ID" = 10113 AND ROWNUM <= 1

明らかに、これによりページの読み込み時間が非常に長くなります。それぞれをループし、親オブジェクトもプルする必要があるからです。

私はいくつかのことを試しました。

> Alert.joins(:polling).where(...)
> Alert.includes(:polling).where(...)
> Alert.joins(:polling).select('*').where(...)

そして、インデックス ページにアクセスするたびに、2 つの異なるクエリを取得します。アラートごとに 1 つ、次にその親データを取得するためにもう 1 つ。アラートをプルしたときに関連する親データも取得できるように、これを 1 行で行うにはどうすればよいですか? 反対側からそれを実行する方法はないようですPollings.where(...)

4

1 に答える 1

3

SQL を詳細に指定したい場合は、いつでもfind:include、:joins、:where などを渡すメソッドを試すことができます。includesまたはjoins、データにアクセスしようとすると、同じことが実行されますが、activerecord の動作が異なります。たとえば、次の 3 つの方法でオブジェクト配列を設定しますが、これらは異なります。

[1]

alerts = Alert.joins(:polling)

[2]

alerts = Alert.includes(:polling)

[3]

alerts = Alert.find(:all, :includes => :polling, :joins => :polling)

あなたがするとき

alerts.each do |alert|
  alert.pollings.each do |polling|
    p polling
  end
end

activerecord が DB またはキャッシュからデータを取得しようとする様子を見ることができます。[3] の方法は、他の人が複数のクエリをスローするときに、1 つのクエリのみをスローすると私は信じています。

于 2012-07-24T20:06:49.030 に答える