Ruby on Rails - Выберите все дочерние ассоциации с соответствующим идентификатором - PullRequest
0 голосов
/ 12 сентября 2018
  • У меня есть user
  • A user has_many orders.
  • order has_many order_items.
  • order_items имеют полиморфную связь с products через items

Я пытаюсь выбрать все orders, которые имеют order_items, которые имеют product, что соответствует моему product_id.

Это существующая кодовая база, и в настоящее время большой рефакторинг невозможен.

Я подошел к проблеме следующим образом:

orders = current_user
          .orders
          .current
          .map { |order| order.order_items }
          .flatten
          .select { |order_item| order_item.item_id.to_s == product_id }
          .map { |order_item| order_item.order }

Этоработает, я просто хочу знать, есть ли лучший или более "Рубиновый способ" сделать это?

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

Старайтесь не запрашивать записи в Ruby вместо Active Record

Основная проблема с кодом, как он написан в настоящее время, заключается в том, что большая часть запросов выполняется с использованием Ruby, а не позволяет базе данных обрабатывать его через Active Record.

Как только вы использовали метод map, вы сказали Active Record вернуть записи из базы данных и создать их экземпляр в памяти.

Путем написания всего запроса с использованием одной только Active Record вы достигнете гораздо большей производительности, избежите многократных запросов И код станет проще.

Использование joins + where предложения

Ключом к вашему запросу является использование joins для связи всех ассоциаций и where для фильтрации их с теми, которые выхочу.

Начните с этого

current_user.orders.joins(:order_items)

Здесь вы можете использовать предложение where для фильтрации по product_id.

current_user.orders.joins(:order_items).where(order_items: { item_id: product_id })

where Предложение может принимать Hash в качестве параметра, и вы можете использовать этот хэш, чтобы указать, что вы хотите фильтровать в объединенной таблице (в данном случае в таблице order_items).


Документация для этого здесь:
https://guides.rubyonrails.org/active_record_querying.html#specifying-conditions-on-the-joined-tables

0 голосов
/ 12 сентября 2018

Получить запись с одним запросом вместо длинного рубинового кода

current_user.orders.left_outer_joins(order_items: :products).select("orders .* order_items.item_id = #{product_id}").group("orders.id")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...