2012-04-09 113 views
71

过滤对象数组所以我执行查询的数据库,我有对象的完整阵列:的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') 

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

干杯

回答

135

尝试:

这是罚款:

@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 
+1

由于@ Vik的解决方案非常理想,我只是在二进制情况下添加这些内容,你可以使用'分区'功能让事情变得更加美好。 http://ruby-doc.org/core-1.9.3/Enumerable.html#method-i-partition – Vlad 2016-06-20 21:04:15

+0

感谢@Vlad,这很酷,但它只支持我们只需要从对象收集两件东西。 – Vik 2016-08-01 07:52:08

+0

是的,这就是为什么我说“二元”:)。在这个问题上,显然有一个标志或图像的选择,所以我加了这个完整性。 – Vlad 2016-08-01 19:04:41

2

你试图预先加载?

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

对不起,我没有说清楚:如何按照对象属性的值进行过滤而不循环数组? – joepour 2012-04-09 07:50:54

+0

如果我理解正确,那么您希望获得更少的db查询,尤其是,一旦执行了诸如“@attachments = Job.first.attachments”之类的查询,您希望循环“@ attachments”,同时您不希望再有任何数据库查询。这是你想要做什么? – 2012-04-09 08:46:53

+0

我做一个数据库查询并接收一个对象数组。然后,我想通过根据属性的值过滤对象来创建两个单独的列表。 - 欢呼声 – joepour 2012-04-09 08:55:52

3

如果你的附件是

@attachments = Job.find(1).attachments 

此附件的将是数组对象

使用选择方法基于FILE_TYPE进行过滤。

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

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