【问题标题】:Efficient ActiveRecord has_and_belongs_to_many query高效的 ActiveRecord has_and_belongs_to_many 查询
【发布时间】:2012-11-29 11:49:19
【问题描述】:

我有具有 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

【问题讨论】:

  • @jdoe 我已经澄清了我的问题,感谢您的努力。
  • 两个查询有什么问题?有没有我们没有看到的更复杂的示例?
  • 不,我只想使用 activerecord 查询执行我的问题中的 SQL。

标签: ruby-on-rails activerecord has-and-belongs-to-many


【解决方案1】:

有了 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])

【讨论】:

  • Association named 'pages_paragraphs' was not found
  • 如果没有 pages_paragraphs 表的模型/关联,您可以将连接条件作为字符串执行。 Page.joins("在 pages_paragraphs.page_id = pages.id 上加入 pages_paragraphs").where("pages_paragraphs.paragraph_id = ?", paragraph_id)
【解决方案2】:

您可以为此使用eager_load

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

我找到了一篇关于这类事情的文章: 3 ways to do eager loading (preloading) in Rails 3 & 4Robert Pankowecki

【讨论】:

    【解决方案3】:

    您可以为此使用includes

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

    【讨论】:

    • includes 使用额外的查询来加载相关数据。 OP 在一个查询中要求全部内容,所以这不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-18
    • 2021-05-13
    • 2018-06-29
    • 2012-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多