2017-02-03 2 views
0

Ich habe eine einfache Frage zu RoR über viele zu viele Beziehung (has_many through:). Also ich habe ein Tweet Modell, das viele Tag hat und umgekehrt.Abfrage-Filterung mit Rails has_many durch

Sie haben eine Indexaktion und Ansicht, in der Sie alle Tweets mit Tags anzeigen, aber Sie haben auch nach Tags gefiltert. Auch gibt es ein kleines Detail, dass ein Tweet ohne ein Tag sein kann.

Also, wenn ich etwas wie folgt aus:

Tweet.includes(:tags).where(tags: { name: #2017 })

Wenn Sie dann filtern, werden Sie nur den Tag bekommen, dass Sie gefiltert, aber nicht alle Tags, dass es für Tweet war. F. e. Wenn Tweet Tags #2017, #2016, #2015 hatten, werden Sie am Ende nur #2017 aus Ihrer Sicht bekommen.

So können Sie das Problem beheben mit so etwas wie dies zu tun:

Tweet.joins(:tags).where(tags: { name: #2017 })

Dann werden Sie alle Tags für jeden Tweet bekommen.

Aber das Problem ist, dass, wenn die Indexseite keine Filter hat, ich alle Tweets anzeigen möchte, Ereignis ohne ein Tag.

Natürlich können Sie einen Hack wie überprüfen, ob das Tag param existiert tun Tweet.joins sonst tun Tweet.includes.

Gibt es eine Möglichkeit, dies innerhalb von 1 Abfrage und ohne Hacks zu tun? Auch was ist die Mechanik dahinter. Ich verstehe die Logik hinter includes or LEFT OUTER JOIN, weil es nur tweet_id und 'tag_id' in Ihrer Zwischentabelle und dann diese ID zu Tag Tabelle, wenn Sie etwas wie where Abfrage oben genannten haben. Aber warum mit INNER JOIN es hält mich alle Tags geben, gibt mir eine Frage.

Danke für die Beantwortung.

Antwort

1

Sein, weil includes macht die eifrigen Laden, wenn Sie abfragen

Tweet.includes(:tags).where(tags: {name: "2017"}) 

Es eifrig lädt alle Tweets mit Tags Namen als 2017. Tweet.tags nicht die db Abfrage erneut ausführen und wird nur ein Wert für Tags haben .

Aber im Falle von verbindet

Tweet.joins(:tags).where(tags: {name: "2017"}) 

Es ist die innner beitreten, und nur die Tweets finden, die Tags und Tag-Namen haben, ist 2017. Nachdem die Tweets zu finden, wenn Sie Tweet.tags tun, ist es die DB-Abfrage läuft Wiederum finden Sie alle zugehörigen Tags, die Ihnen das gewünschte Ergebnis liefern.

Verwandte Themen