Rails фильтрует массив объектов по значению атрибута

Поэтому я выполняю запрос к БД, и у меня есть полный массив объектов:

@attachments = Job.find(1).attachments

Теперь, когда у меня есть массив объектов, я не хочу выполнять другой запрос БД, но я бы хотел отфильтровать массив на основе объекта Attachment file_type чтобы у меня был список attachments которых тип файла - 'logo' а затем еще один список attachments где тип файла 'image'

Что-то вроде этого:

@logos  = @attachments.where("file_type = ?", 'logo')
@images = @attachments.where("file_type = ?", 'image')

Но в памяти вместо запроса БД.

Ответ 1

Попробуйте:

Это нормально:

@logos = @attachments.select { |attachment| attachment.file_type == 'logo' }
@images = @attachments.select { |attachment| attachment.file_type == 'image' }

но для повышения производительности вам не нужно дважды итерации @attachments:

@logos , @images = [], []
@attachments.each do |attachment|
  @logos << attachment if attachment.file_type == 'logo'
  @images << attachment if attachment.file_type == 'image'
end

Ответ 2

Если ваши вложения

@attachments = Job.find(1).attachments

Это будет массив объектов привязки

Использовать метод select для фильтрации на основе file_type.

@logos = @attachments.select { |attachment| attachment.file_type == 'logo' }
@images = @attachments.select { |attachment| attachment.file_type == 'image' }

Это не вызовет какой-либо запрос db.

Ответ 3

Вы пытались с нетерпением загружать?

@attachments = Job.includes(:attachments).find(1).attachments

Ответ 4

Вы можете фильтровать, используя где

Job.includes(:attachments).where(file_type: ["logo", "image"])

Ответ 5

Я бы пошел об этом немного по-другому. Структурируйте свой запрос, чтобы получить только то, что вам нужно, и разбить его оттуда.

Поэтому сделайте ваш запрос следующим:

#                                vv or Job.find(1) vv
attachments = Attachment.where(job_id: @job.id, file_type: ["logo", "image"])
# or 
Job.includes(:attachments).where(id: your_job_id, attachments: { file_type: ["logo", "image"] })

А затем разделите данные:

@logos, @images = attachments.partition { |attachment| attachment.file_type == "logo" }

Это позволит получить данные, которые вы ищете в аккуратной и эффективной манере.