Rails按属性值过滤对象数组

问题描述 投票:87回答:5

所以我对db执行查询,我有一个完整的对象数组:

@attachments = Job.find(1).attachments

现在我有一个对象数组,我不想执行另一个数据库查询,但我想基于Attachment对象的file_type过滤数组,这样我就可以有一个attachments列表,其中文件类型是'logo'然后另一个attachments列表,其中文件类型是'image'

像这样的东西:

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

但是在内存中而不是db查询。

ruby-on-rails activerecord
5个回答
163
投票

试试:

这可以 :

@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

8
投票

如果您的附件是

@attachments = Job.find(1).attachments

这将是附件对象的数组

使用select方法根据file_type进行过滤。

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

这不会触发任何数据库查询。


2
投票

你试过加载吗?

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

0
投票

您可以使用where过滤

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

0
投票

我对此略有不同。构建查询以仅检索所需内容并从中进行拆分。

因此,请进行以下查询:

#                                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" }

这将以一种整洁有效的方式获得您所追踪的数据。

© www.soinside.com 2019 - 2024. All rights reserved.