Ich habe eine Rails-Anwendung, die Stationen (Wetterstationen) und Beobachtungen hat. Die App zeigt viele Wetterstationen auf einer Karte mit der aktuellen Windgeschwindigkeit und Richtung.Schienen begier_load mit Bedingungen für die Zuordnung
Ich habe eine Methode, die auf der stations#index
Methode verwendet wird, die die Stationen auswählt und die neueste Beobachtung pro Station verbindet.
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
gibt ein Array von IDs zurück. Die observations
Tabelle enthält viele Tausende von Zeilen, so dass dies erforderlich ist, um zu verhindern, dass Schienen tausende von Datensätzen geladen werden. Diese Methode sollte alle Stationen Rückkehr
- ob das irgendwelche Beobachtungen oder nicht. Dies ist jedoch derzeit nicht der Fall.
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
Von meinem Verständnis ein LEFT OUTER JOIN
sollten alle Zeilen zurückgeben, ob die es Ergebnisse in der verknüpften Tabelle sind oder nicht. Warum funktioniert das nicht wie erwartet?
Dies ist ein Beispiel für die SQL generiert:
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);
'" Beobachtungen "." ID "IN (..)' Sollte innerhalb der ON-Klausel und nicht der WHERE-Klausel sein. – sagi