Эффективный запрос 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
Ответ 3
Вы можете использовать eager_load
для этого
pages = Paragraph.eager_load(:pages).find(paragraph_id).pages
Я нашел статью о таких вещах:
3 способа выполнить загрузку (предварительную загрузку) в Rails 3 и 4 Роберт Панковецки