13

我有具有 has_and_belongs_to_many 关系的 Page 和 Paragraph 模型。给定一个paragraph_id,我想获得所有匹配的页面。例如:

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
4

3 回答 3

21

使用 has_many :through 关系,您可以使用:

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])
于 2012-11-29T14:34:35.863 回答
2

你可以用eager_load这个

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

我发现了一篇关于这类事情的文章: Robert Pankowecki在 Rails 3 和 4 中进行急切加载(预加载)的 3 种方法

于 2017-04-13T06:19:04.677 回答
1

您可以includes为此使用:

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

于 2012-11-29T11:57:20.823 回答