2017-02-21 4 views
0

Ich möchte eine Eager laden, aber eine Where-Klausel auf die Abfrage Eager laden.Eager laden Active Record Association mit WHERE auf Join-Klausel

Lassen Sie uns sagen, wir haben die folgenden:

class Features < ActiveRecord::Base 
    has_many :feature_overrides 
end 

class FeatureOverride < ActiveRecord::Base 
    belongs_to :feature 
end 

Wenn ein Merkmal ein active Attribut hat, die durch eine Funktion überschreiben außer Kraft gesetzt werden kann.

Featureüberschreibungen werden für Benutzer hinzugefügt, sodass das Attribut active für ein Feature durch eine Featureüberschreibung für einen bestimmten Benutzer außer Kraft gesetzt werden kann.

Hier ist die Abfrage Ich habe die feature_overrides alle Funktionen und eifrig Last zu erhalten:

Features.all.includes(:feature_overrides) 

Mit dieser Abfrage, die ich immer noch die feature_overrides suchen müsste, um zu sehen, ob es ein Feature Überschreibung für einen bestimmten Benutzer vorhanden . ein, wo an der eifrigen Last Hinzufügen nicht geben Sie mir, was ich will:

Features.all.includes(:feature_overrides).where('feature_overrides.username = ?', username) 

Dies wird mein Ergebnis reduzieren nur Funktionen enthalten, wo es eine Überschreibung für username existiert.

An diesem Punkt denke ich, was ich will, ist eine Linke Outer Join, aber wenn ich versuche, dass Active Record deserialize die Feature Override Association.

würde ich die eifrig Last mag irgendwie die Abfragen ausführen:

SELECT `features`.* FROM `features` 
SELECT `feature_overrides`.* FROM `feature_overrides` WHERE `feature_overrides`.`feature_id` IN (...) AND `feature_overrides`.`username` = ? 
+0

Wenn Sie Funktionen benötigen, die vom Benutzer überschrieben wurden, können Sie Folgendes tun: 'FeatureOverride.where (Benutzername: Benutzername) .includes (: feature)'. – Psylone

+0

Danke für deine Antwort! Ich mache tatsächlich ein bisschen mehr mit den Features, ich nehme an, dass ich sie von dieser Abfrage bekommen kann, indem ich FeatureOverride.where (username: username) .includes (: feature) .features mache, aber meine Situation ist ein bisschen komplizierter als das ... – superJustin

+0

Verstanden, ein anderer Weg ist die 'Joins' ActiveRecord Methode. Wahrscheinlich können Sie Folgendes tun: 'Feature.joins (: feature_overrides) .where ('feature_overrides.username =?', Username)'. – Psylone

Antwort

0

Das ist also klingen wie Sie die Left Outer Join müssen (genau das, was Sie in der Frage geschrieben, aber mein Geist war geblendet). Wenn Sie auf Rails sind 5 versuchen, dies zu verwenden:

Feature.left_outer_joins(:feature_overrides) 

Wenn Sie auf Rails sind 4 müssen Sie diese ein manuell schreiben:

Feature.joins(%[LEFT OUTER JOIN 'feature_overrides' ON 'feature_overrides'.'feature_id' = 'features'.'id']) 

Sie auch anhängen where Bereich, wenn Sie feature_overrides durch die username filtern müssen.