Ruby-on-rails Rails 按属性值过滤对象数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10069993/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Rails filtering array of objects by attribute value
提问by joepour
So I perform a query to the db and I have a complete array of objects:
所以我对数据库执行查询,我有一个完整的对象数组:
@attachments = Job.find(1).attachments
Now that I have an array of objects I don't want to perform another db query, but I would like to filter the array based on the Attachmentobject's file_typeso that I can have a list of attachmentswhere the file type is 'logo'and then another list of attachmentswhere the file type is 'image'
现在,我有对象,我不想执行另一个数据库查询的数组,但我想基于对数组筛选Attachment对象的file_type,这样我可以有一个列表attachments,其中文件类型为'logo',然后另一个列表attachments哪里文件类型是'image'
Something like this:
像这样的东西:
@logos = @attachments.where("file_type = ?", 'logo')
@images = @attachments.where("file_type = ?", 'image')
But in memory instead of a db query.
但是在内存中而不是 db 查询。
回答by Vik
Try :
尝试 :
This is fine :
这可以 :
@logos = @attachments.select { |attachment| attachment.file_type == 'logo' }
@images = @attachments.select { |attachment| attachment.file_type == 'image' }
but for performance wise you don't need to iterate @attachments twice :
但是为了提高性能,您不需要重复 @attachments 两次:
@logos , @images = [], []
@attachments.each do |attachment|
@logos << attachment if attachment.file_type == 'logo'
@images << attachment if attachment.file_type == 'image'
end
回答by Soundar Rathinasamy
If your attachments are
如果您的附件是
@attachments = Job.find(1).attachments
This will be array of attachment objects
这将是附件对象数组
Use select method to filter based on file_type.
使用 select 方法根据 file_type 进行过滤。
@logos = @attachments.select { |attachment| attachment.file_type == 'logo' }
@images = @attachments.select { |attachment| attachment.file_type == 'image' }
This will not trigger any db query.
这不会触发任何数据库查询。
回答by u445908
have you tried eager loading?
你试过急切加载吗?
@attachments = Job.includes(:attachments).find(1).attachments
回答by Darlan Dieterich
You can filter using where
您可以使用 where 进行过滤
Job.includes(:attachments).where(file_type: ["logo", "image"])
回答by SRack
I'd go about this slightly differently. Structure your query to retrieve only what you need and split from there.
我会略有不同。构造您的查询以仅检索您需要的内容并从那里拆分。
So make your query the following:
所以让你的查询如下:
# 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"] })
And then partition the data:
然后对数据进行分区:
@logos, @images = attachments.partition { |attachment| attachment.file_type == "logo" }
That will get the data you're after in a neat and efficient manner.
这将以简洁有效的方式获取您所需要的数据。

