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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 03:11:53  来源:igfitidea点击:

Rails filtering array of objects by attribute value

ruby-on-railsactiverecord

提问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.

这将以简洁有效的方式获取您所需要的数据。