Ich habe folgenden Code:
@posts = Post.joins(:user).joins(:blog).select
Dies soll alle Beiträge finden und sie sowie die zugehörigen Benutzer und Blogs zurückgeben. Jedoch Benutzer sind optional , was bedeutet , dass die , INNER JOIN
die :joins
nicht zurückkehr viele Datensätze erzeugt.
Wie verwende ich dies, um LEFT OUTER JOIN
stattdessen eine zu generieren ?
ruby-on-rails
ruby
activerecord
Neil Middleton
quelle
quelle
Antworten:
quelle
@posts = Post.joins("LEFT OUTER JOIN users ON users.id = posts.user_id").joins(:blog).where("users.id IS NULL").select
select('posts.*')
?Sie können dies tun,
includes
wie im Rails-Handbuch dokumentiert :Ergebnisse in:
quelle
includes
geht kein Join hervor, sondern eine separate Abfrage, um die Zuordnung zu erhalten. So wird N + 1 vermieden, jedoch nicht auf die gleiche Weise wie bei einem JOIN, bei dem die Datensätze in einer Abfrage abgerufen werden.includes
, auf das Sie achtenincludes
2 Abfragen anstelle von a generiert werden,JOIN
wenn Sie keine benötigenWHERE
.references(:comments)
. Darüber hinaus führt dies dazu, dass alle zurückgegebenen Kommentare aufgrund vonincludes
, was möglicherweise nicht das ist, was Sie möchten , eifrig in den Speicher geladen werden .Post.includes(:comments).where(comments: {visible: true})
. Auf diese Weise müssen Sie auch nicht verwendenreferences
.Ich bin ein großer Fan des Squeel-Edelsteins :
Es unterstützt sowohl
inner
undouter
verbindet, sowie die Fähigkeit , eine Klasse / Typ für polymorphe belongs_to Beziehungen zu spezifizieren.quelle
Verwendung
eager_load
:quelle
Wenn Sie
ActiveRecord::Base#joins
eine benannte Zuordnung übergeben, wird standardmäßig eine INNERE VERBINDUNG ausgeführt. Sie müssen eine Zeichenfolge übergeben, die Ihren LEFT OUTER JOIN darstellt.Aus der Dokumentation :
quelle
In activerecord befindet sich eine left_outer_joins- Methode. Sie können es so verwenden:
quelle
Gute Nachrichten, Rails 5 unterstützt jetzt
LEFT OUTER JOIN
. Ihre Anfrage würde nun folgendermaßen aussehen:quelle
quelle