2012-07-24 1 views
5

ich eine Eltern/Kind-Beziehung in meiner AnwendungRails Active Record wählen Eltern und Kind als ein Ergebnis

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

class Alert 
belongs_to :polling 

Auf meiner Index-Seite für die Warnungen haben, muss ich von jedem Elternteil einige Daten zeigen, und dies in zwei Abfragen Ergebnisse

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 

Offensichtlich macht dies die Ladezeit ganz entsetzlich, wie es durch jede Schleife hat und das übergeordnete Objekt als auch ziehen.

Ich habe ein paar Dinge ausprobiert, wie

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

Und jedes Mal, wenn ich zwei verschiedene Abfragen, wenn ich meine Index-Seite. Eine für jede Warnung und eine weitere, um ihre übergeordneten Daten zu erhalten. Wie kann ich dies in einer Zeile tun, so dass, wenn ich die Warnungen abrufe, ich auch ihre zugehörigen Elterndaten bekomme? Es scheint keinen Weg zu geben, es vom anderen Ende aus zu tun, denn wenn ich eine mache, ergreift es die Kinder nicht als Gruppe.

+1

Mit der includes-Methode sind Sie definitiv auf dem richtigen Weg. Der andere Winkel wäre Polling.includes (: Warnungen) .where (...). Können Sie Ihren Ansichtscode posten? – steakchaser

+0

Die Sache ist, wir müssen es von der Kinderseite, nicht von der Elternseite gehen. – Oranges13

+0

Willst du keine Vorspannung? http://apidock.com/rails/ActiveRecord/AssociationPreload/ClassMethods/preload_associations – toxaq

Antwort

2

Wenn Sie SQL im Detail angeben möchten, können Sie immer versuchen find Passing-Verfahren: umfassen: beitritt,: wo usw. includes oder joins elbe tut der ganzen Linie, wenn Sie versuchen, auf Daten zuzugreifen, aber das Verhalten von Active ist anders. Wenn Sie beispielsweise 3 verschiedene Arten von Objekt-Arrays einrichten, sind diese unterschiedlich.

[1]

alerts = Alert.joins(:polling) 

[2]

alerts = Alert.includes(:polling) 

[3]

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

wenn Sie das tun

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

können Sie sehen, wie activerecord versucht, Daten aus DB oder Cache zu bekommen. Die [3] Weise, glaube ich, wirft nur eine Abfrage, wenn andere mehrere Abfragen werfen.

+0

Ich habe festgestellt, dass selbst wenn ich die Alert.find mit einem Join mache, wenn ich alert.pollings verwende, zieht es diese immer noch getrennt von der Datenbank zurück , das war es, was die zusätzlichen Abfragen verursachte. Am Ende habe ich auch eine .select() verwendet und alert.polling_field funktioniert wie beabsichtigt. Seltsam, aber es funktioniert. – Oranges13