Rails, как запросить вложенные ассоциации, возвращая все вложенные ассоциации - PullRequest
0 голосов
/ 26 октября 2018

У меня есть следующие ассоциации:

class User < ApplicationRecord
  has_many :orders
end

class Order < ApplicationRecord
  belongs_to :user
  has_one :invoice
end

class Invoice < ApplicationRecord
  belongs_to :order
  has_one :receipt
end

class Receipt < ApplicationRecord
  belongs_to :invoice
end

Я хочу вернуть все чеки по всем заказам, которые есть у пользователя.

Если бы отношения были один к одному на всем пути вниз, это было бы просто:

user = User.find(...)

user.order.invoice.receipt

Поскольку есть много заказов, я обнаружил, что хочу нанести на карту и сгладить. Я не хочу этого делать. Кажется, я не могу найти источники, которые помогают мне по-настоящему обмануть эту концепцию. Нужно ли мне определять отношение through? мне нужно использовать .joins?

Как вернуть квитанцию ​​по счету на все заказы, принадлежащие конкретному пользователю?

Ответы [ 2 ]

0 голосов
/ 26 октября 2018

Другой вариант - использование подзапроса.

users = User.where(id: user_id)
orders = Order.where(user_id: users)
invoices = Invoice.where(order_id: orders)
receipts = Receipt.where(invoice_id: invoices)

При загрузке receipts вышеприведенный запрос должен выполнить один запрос.При копировании в суффикс терминала строки с ;nil для предотвращения метода inspect (который используется для отображения возвращаемого значения терминала) для загрузки коллекций.


Примечание: Обычно вам необходимо указать атрибут для выбора.Однако атрибут id (первичный ключ) выбирается неявным образом, не выбирая атрибут.

orders = Order.where(user_id: users)
# is the same as
orders = Order.where(user_id: users.select(:id))

Имейте это в виду, когда необходимо создать подзапрос на основе другого атрибута, чем ID .Например, при изменении направления подзапроса.

users = User.where(id: orders.select(:user_id))
0 голосов
/ 26 октября 2018

Это должно работать для вас:

Receipt.joins(invoice: { order: :user }).where(users: { id: user_id })

Да, вам нужно использовать объединения для генерации правильного запроса (объедините все таблицы по пути и добавьте ограничения для пользователей).

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