Список вложений ActiveStorage, косвенно связанных с моделью - PullRequest
0 голосов
/ 10 сентября 2018

Я новичок в Rails и пытаюсь понять, как работает ActiveStorage.

Приложение имеет следующие модели:

class Client < ApplicationRecord
    has_many :jobs
    has_many :messages
end
class Job < ApplicationRecord
    belongs_to :client
    has_many_attached :images
end
class Message < ApplicationRecord
    belongs_to :client
    has_many_attached :images
end

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

Однако мне было интересно, есть ли идиоматичный и эффективный способ получить все вложения, связанные с клиентом?

Ответы [ 2 ]

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

Запрос вложений, связанных с данной записью

Вы можете запросить вложения напрямую, используя класс ActiveStorage::Attachment. Атрибут record - это полиморфная ассоциация, которая присоединяется к присоединенному классу.

Вот пример

ActiveStorage::Attachment.where(record: Job.first)

Запрос вложений, связанных с набором записей

Вы также можете передать набор записей в опцию record

ActiveStorage::Attachment.where(record: Job.all)

Запрос вложений, связанных с несколькими наборами записей

Вы можете найти вложения, связанные с несколькими наборами записей, используя or

ActiveStorage::Attachment.where(record: Job.all).or(ActiveStorage::Attachment.where(record: Message.all))

Собираем это вместе ...

Чтобы найти все вложения, связанные с несколькими наборами записей, связанных с данной записью

client = Client.first
ActiveStorage::Attachment.where(record: client.jobs).or(ActiveStorage::Attachment.where(record: client.messages))

Это не красиво, но эффективно. Все запросы выполняются через Active Record, что означает, что это происходит в одном операторе SQL и не требует загрузки каких-либо объектов в память.

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

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

#ask for first client and all messages
oneClient = Client.first
allImages = []
oneClient.message.all.each do |msg|
  #ask for the all images of each message
  msg.image.all.each do |img|
    img << allImages
  end
end
#repeat block for Job
oneClient.job.all.each do |jb|
  jb.image.all.each do |img|
    img << allImages
  end
end

Приведенный выше блок должен дать вам отношение одного Клиента ко всем его сообщениям и ко всем его изображениям.

...