2012-11-29 85 views
10

我有一個has_and_belongs_to_many關係的頁面和段落模型。鑑於一個paragraph_id,我想獲得所有匹配的頁面。例如:高效的ActiveRecord has_and_belongs_to_many查詢

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

但是,這需要兩個查詢。它可以在一個查詢來完成:

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

但是可以將此不

  • 使用的find_by_sql
  • 不修改到page_paragraphs臺(例如添加一個id)來完成。

更新:

我的頁面模式是這樣的:

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

@jdoe我澄清我的問題,謝謝各位的努力。 –

+0

兩個查詢有什麼問題?有沒有更復雜的例子,您正試圖優化,我們沒有看到? –

+0

不,我只是想用activerecord查詢在我的問題中執行SQL。 –

回答

1

您可以使用includes此:

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

+4

這產生2個查詢。 –

15

憑藉的has_many:通過關係,你可以使用這個:

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

看看指定條件的連接表這裏:http://guides.rubyonrails.org/active_record_querying.html

如果你想要的頁面和段落在一起:

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

隨着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

'沒有找到名爲'pages_paragraphs'的關聯' –

+1

沒有您的pages_paragraphs表的模型/關聯,您可以將連接條件作爲字符串來執行。 Page.joins(「在pages_paragraphs.page_id = pages.id上加入pages_paragraphs」)。where(「pages_paragraphs.paragraph_id =?」,paragraph_id) –