Эффективный запрос ActiveRecord has_and_belongs_to_many

У меня есть модели страниц и абзацев с отношением has_and_belongs_to_many. Учитывая 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 (например, добавление идентификатора).

Update:

Моя модель страницы выглядит следующим образом:

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

Ответ 1

С 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])

Ответ 2

Вы можете использовать includes для этого:

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