104

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

@attachments = Job.find(1).attachments

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

像这样的东西:

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

但是在内存中而不是数据库查询中。

4

6 回答 6

182

尝试 :

这可以 :

@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
于 2012-04-09T11:16:39.460 回答
10

如果您的附件是

@attachments = Job.find(1).attachments

这将是附件对象的数组

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

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

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

于 2012-04-09T10:22:18.410 回答
2

您是否尝试过急切加载?

@attachments = Job.includes(:attachments).find(1).attachments
于 2012-04-09T07:07:58.487 回答
2

对于较新版本的 ruby​​,您可以使用

@logos = @attachments.filter { |attachment| attachment.file_type == 'logo' }

参考:https ://apidock.com/ruby/Array/filter

于 2021-06-10T06:24:18.903 回答
0

您可以使用 where 过滤

Job.includes(:attachments).where(file_type: ["logo", "image"])
于 2019-03-12T11:48:00.333 回答
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" }

这将以简洁有效的方式获得您所追求的数据。

于 2019-06-12T15:07:24.193 回答