私は局(天気予報局)と観測点を持つRailsアプリケーションを持っています。このアプリは現在の風速と方向で地図上に多くの気象観測所を表示します。Rails eager_load関連の条件付き
私はステーションを選択し、ステーションごとに最新の観測を結合する方法で使用される方法を持っています。
class Station < ActiveRecord::Base
has_many :observations
def self.with_observations(limit = 1)
eager_load(:observations).where(
observations: { id: Observation.pluck_from_each_station(limit) }
)
end
end
Observation.pluck_from_each_station
は、IDの配列を返します。 observations
テーブルには何千もの行が含まれているので、レールを熱心に読み込んで何千ものレコードをロードする必要があります。
この方法は、の観測結果がであるかどうかにかかわらず、すべてのステーションを返す必要があります。しかし、現在はそうではありません。結合テーブルかどうかのいずれかの結果がある天気を私の理解LEFT OUTER JOIN
から
it "includes stations that have no observations" do
new_station = create(:station)
stations = Station.with_observations(2)
expect(stations).to include new_station # fails
end
は、すべての行を返す必要があります。これが期待どおりに機能しないのはなぜですか?
eager_load(:observations).where(
'"observations"."id" is null or "observations"."id" in (?)', Observation.pluck_from_each_station(limit)
)
それは論理的に次のとおりです。uはレコードを除いているためleft join
後"observations"."id"
がnullであり、私はそれが起こると思います
SELECT "stations"."id" AS t0_r0,
"stations"."name" AS t0_r1,
"stations"."hw_id" AS t0_r2,
"stations"."latitude" AS t0_r3,
"stations"."longitude" AS t0_r4,
"stations"."balance" AS t0_r5,
"stations"."timezone" AS t0_r6,
"stations"."user_id" AS t0_r7,
"stations"."created_at" AS t0_r8,
"stations"."updated_at" AS t0_r9,
"stations"."slug" AS t0_r10,
"stations"."speed_calibration" AS t0_r11,
"stations"."firmware_version" AS t0_r12,
"stations"."gsm_software" AS t0_r13,
"stations"."description" AS t0_r14,
"stations"."sampling_rate" AS t0_r15,
"stations"."status" AS t0_r16,
"observations"."id" AS t1_r0,
"observations"."station_id" AS t1_r1,
"observations"."speed" AS t1_r2,
"observations"."direction" AS t1_r3,
"observations"."max_wind_speed" AS t1_r4,
"observations"."min_wind_speed" AS t1_r5,
"observations"."temperature" AS t1_r6,
"observations"."created_at" AS t1_r7,
"observations"."updated_at" AS t1_r8,
"observations"."speed_calibration" AS t1_r9
FROM "stations"
LEFT OUTER JOIN
"observations"
ON "observations"."station_id" = "stations"."id"
WHERE "observations"."id" IN (450, 500, 550, 600, 650, 700, 750, 800);
'' observations "。" id "IN(..)' ''句の中で、 'WHERE'節ではないはずです。 – sagi