2012-11-29 4 views
10

Ich habe Seiten-und Absatzmodelle mit einer has_and_belongs_to_many Beziehung. Bei einer Absatz-ID möchte ich alle übereinstimmenden Seiten erhalten. Beispiel:Efficient ActiveRecord has_and_belongs_to_many Abfrage

pages = Paragraph.find(paragraph_id).pages.all 

Dies erfordert jedoch zwei Abfragen.

SELECT "pages".* FROM "pages" 
INNER JOIN "pages_paragraphs" ON "pages_paragraphs"."page_id" = "pages"."id" 
WHERE "pages_paragraphs"."paragraph_id" = 123 

Aber kann dies ohne

  • mit find_by_sql
  • ohne Modifikationen an der page_paragraphs Tabelle (zum Beispiel eine ID Zugabe) durchgeführt werden: Es kann in einer Abfrage durchgeführt werden.

Update:

Meine Seite Modell wie folgt aussieht:

class Page < ActiveRecord::Base 
    has_and_belongs_to_many :paragraphs, uniq: true 
end 
+0

@jdoe ich meine Frage geklärt haben, Dank für Ihre Bemühungen. –

+0

Was ist das Problem mit zwei Abfragen? Gibt es ein komplizierteres Beispiel, das Sie zu optimieren versuchen, das wir nicht sehen? –

+0

Nein, ich möchte nur die SQL in meiner Frage mit einer ActiveRecord-Abfrage ausführen. –

Antwort

1

können Sie includes für diesen Einsatz:

pages = Paragraph.includes(:pages).find(paragraph_id).pages

+4

Das erzeugt 2 Abfragen. –

15

Mit einem has_many: durch Beziehung, Sie könnten dies verwenden:

pages = Page.joins(:pages_paragraphs).where(:pages_paragraphs => {:paragraph_id => 1}) 

Werfen Sie einen Blick auf mit Bedingungen für die verbundenen Tabellen hier: http://guides.rubyonrails.org/active_record_querying.html

Wenn Sie die Seiten und Absätze wollen zusammen:

pages = Page.joins(:pages_paragraphs => :paragraph).includes(:pages_paragraphs => :paragraph).where(:pages_paragraphs => {:paragraph_id => 1}) 

Mit einem has_and_belongs_to_many:

pages = Page.joins("join pages_paragraphs on pages.id = pages_paragraphs.page_id").where(["pages_paragraphs.paragraph_id = ?", paragraph_id]) 
+0

'Assoziation namens 'pages_paragraphs' wurde nicht gefunden ' –

+1

Ohne das Modell/die Assoziation für Ihre pages_paragraphen-Tabelle können Sie die Join-Bedingungen als Strings ausführen. Page.joins ("join pages_paragraphs auf pages_paragils.page_id = pages.id"). Where ("seiten_paragse.paragraph_id =?", Paragraph_id) –