Получить связанные записи с помощью объединений - PullRequest
0 голосов
/ 11 июня 2018

У меня есть категория, книга, модели заказа

Category.rb

has_many :books

Book.rb

belongs_to :category
has_many :orders

Order.rb

belongs_to :book.

Моя задача - получить заказы, размещенные в определенной категории.

Я пробовал эти два варианта:

Использование объединений

Order.joins(:book => :category).where('books.category_id = ?', 138)

И использование двух запросов:

  1. Чтобы найти book_ids, который находится подопределенная категория

  2. Узнайте заказы, у которых есть эти book_ids

    book_ids = Book.where (: category_id => 138) .pluck (: id)

    Order.where (: book_id => book_ids).

Интересно, какой из них правильный.Как я могу получить заказы, размещенные в определенной категории?

Ответы [ 2 ]

0 голосов
/ 11 июня 2018

По моему опыту, в рельсах лучше использовать includes, так как он использует меньше запросов, чем объединение, что дает лучшую производительность- https://apidock.com/rails/ActiveRecord/QueryMethods/includes

Order.includes(:categories).where('categories.id = ?', id).references(:categories)

Это действительно зависит откак вам нравится читать то, что происходит для понимания.

0 голосов
/ 11 июня 2018

Ваш первый подход выглядит правильно и как будто он должен работать.Я бы настроил его на «Railsy», как показано ниже:

Order.joins(book: :category).where(books: { categories: { id: 138 } })

Редактировать: На самом деле, говоря, что, если вы заранее знаете идентификатор своей категории, вы можетевообще пропустите загрузку категории следующим образом:

Order.joins(:book).where(books: { category_id: 138 })

Это будет намного эффективнее, чем второй подход, так как Rails оптимизирует запрос к базе данных, при этом вам не нужно будет хранить идентификаторы книг в памятизатем сделайте вторую транзакцию.

Если вы хотите получить доступ к атрибутам book или вложенного category заказа, вы должны переключить joins на includes - это предварительно загрузит все необходимых записей и позволяют вам получить доступ к их атрибутам без интенсивных и неэффективных запросов N + 1.

Это отвечает на ваш вопрос?У вас есть проблемы с этим подходом?Если вам нужно что-то прояснить, дайте мне знать, и я буду обновлять по мере необходимости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...