Rails filtering array of objects by attribute value

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 Attachment object's file_type so that I can have a list of attachments where the file type is 'logo' and then another list of attachments where the file type is 'image'

Something like this:

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

But in memory instead of a db query.


Solution 1:

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 :

@logos , @images = [], []
@attachments.each do |attachment|
  @logos << attachment if attachment.file_type == 'logo'
  @images << attachment if attachment.file_type == 'image'
end

Solution 2:

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.

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

This will not trigger any db query.

Solution 3:

have you tried eager loading?

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

Solution 4:

For newer versions of ruby, you can use

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

Reference: https://apidock.com/ruby/Array/filter