2012-11-29 17 views
10

I modelli di pagina e paragrafo hanno una relazione has_and_belongs_to_many. Dato un paragraph_id, mi piacerebbe avere tutte le pagine corrispondenti. ad esempioActiveRecord efficiente has_and_belongs_to_many query

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

Tuttavia, questo richiede due query. Si può fare in una query:

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

Ma questo può essere fatto senza

  • utilizzando find_by_sql
  • senza modifiche alla tabella page_paragraphs (per esempio aggiungendo un id).

Aggiornamento:

Il mio modello pagina si presenta così:

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

@jdoe ho chiarito la mia domanda, grazie per i vostri sforzi. –

+0

Qual è il problema con due query? C'è un esempio più complicato che stai cercando di ottimizzare che non stiamo vedendo? –

+0

No, voglio solo eseguire l'SQL nella mia domanda con una query activerecord. –

risposta

1

È possibile utilizzare includes per questo:

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

+4

Questo produce 2 query. –

15

Con una has_many: attraverso la relazione, potresti usare questo:

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

Date un'occhiata a Specifica delle condizioni sulle Tabelle unite qui: http://guides.rubyonrails.org/active_record_querying.html

Se si desidera che le pagine ei paragrafi insieme:

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

con un 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

'Associazione non denominata 'pages_paragraphs' non trovata ' –

+1

Senza un modello/associazione per la tabella pages_paragraphs, è possibile eseguire le condizioni di join come stringhe. Page.joins ("join pages_paragraphs on pages_paragraphs.page_id = pages.id"). Where ("pages_paragraphs.paragraph_id =?", Paragraph_id) –

Problemi correlati