Формат ActiveRecord объединяется в массив - PullRequest
0 голосов
/ 31 января 2020

Я бы хотел повысить эффективность одной из моих конечных точек. Вот краткое изложение:

В базе данных mysql у нас есть три примера таблиц, две из которых являются таблицами соединения с первой.

:user has_many: :orders 
:user has_many: :attributes

Запрос сиквела прост (но при условии изменить):

User.left_joins(:orders, :attributes).select("users.*, orders.*, attributes.*")

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

[
  {
    User:
     id: 1,
     order_id: 1,
     order_columns_here,
     attribute_id: 1,
     attribute_columns_here
  },
  {
    User:
     id: 1,
     order_id: 2,
     order_columns_here,
     attribute_id: 2,
     attribute_columns_here
  }
]

Результатом является массив одних и тех же пользовательских данных, повторяемый несколько раз для каждого заказа или атрибута, связанного с ним.

Если мне нужно написать ruby, чтобы отформатировать этот объект так, как запрашивается API, он будет медленным ( у нас огромный дб). Есть ли метод активной записи, который я могу использовать для дополнения этого запроса, чтобы данные возвращались со всеми фотографиями и планами этажей в массиве?

т.е.

[
  {
    User: id: 1, orders: [all_order_data_for_user_1], attributes: [all_attributes_data_for_user_1]
  }
]

Последние пару лет я Я использую драгоценный камень сиквела, который делает это для меня. Я прочитал большую часть AR документации, и не уверен, что мне поможет здесь из мира ActiveRecord.

Есть идеи?

РЕДАКТИРОВАТЬ

Mysql версия: mysql Версия 14.14 Распределение 5.7.29 Рельсы: 5 Ruby: 2.3.1

1 Ответ

0 голосов
/ 02 февраля 2020

Если вы заранее знаете, что будете использовать обе ассоциации, вы можете использовать .eager_load, который загрузит все связанные элементы в одном запросе:

User.eager_load(:orders, :attributes)

Если вы не совсем знаете вас может использовать своего нерешительного близнеца .includes, который пытается быть умным и может создать один-два запроса в зависимости от того, как он используется, от того, как дует ветер и от фазы луны.

Это позволяет итерировать, хотя записывает и вызывает ассоциацию, не создавая n + 1 запросов:

User.eager_load(:orders, :attributes).each |user|
  puts user.order.inspect
end

Но вы обычно передаете данные в формат сериализатора или jbuilder для форматирования.

См .: Предварительная загрузка, Eagerload, включает и объединяет

...