2012-04-09 8 views
71

Por lo tanto, realizar una consulta a la base de datos y tengo una gama completa de objetos:rieles de filtrado matriz de objetos por valor de atributo

@attachments = Job.find(1).attachments 

Ahora que tengo una matriz de objetos que no desea llevar a cabo otra consulta db, pero me gustaría para filtrar la matriz basada en la Attachment objeto de file_type para que pueda tener una lista de attachments, donde el tipo de archivo es 'logo' y luego otra lista de attachments, donde el tipo de archivo es 'image'

Algo como este:

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

Pero en memoria en lugar de una consulta db.

Cheers

Respuesta

135

Probar:

Esto está bien:

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

pero para un rendimiento inteligente que no es necesario para recorrer @ attachments dos veces:

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

Como la solución de @ Vik es bastante ideal, solo agregaré eso en casos binarios, podrías usar una función de 'partición' para hacer las cosas dulces. http://ruby-doc.org/core-1.9.3/Enumerable.html#method-i-partition – Vlad

+0

Gracias @Vlad, eso es genial, pero solo es compatible si tenemos que recopilar solo dos cosas del objeto. – Vik

+0

Sí, es por eso que dije "binario" :). En la pregunta, aparentemente había una opción de logotipo o imagen, así que lo agregué para completarlo. – Vlad

2

¿Ha intentado impaciente por cargar?

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

Lo siento, no estoy siendo claro: cómo ¿Filtro por el valor de un atributo de objeto sin recorrer la matriz? – joepour

+0

Si entendí correctamente, quiere menos consulta de db, especialmente, una vez que se ejecuta una consulta como '@attachments = Job.first.attachments', desea hacer un bucle de' @ attachments' mientras tanto, no quiere más consultas de db . es esto lo que quieres hacer? –

+0

Hago una consulta db y recibo una matriz de objetos. Luego quiero crear dos listas separadas a partir de esa única matriz filtrando los objetos en función del valor de sus atributos (Ver publicación original) - ovaciones – joepour

3

Si sus archivos adjuntos son

@attachments = Job.find(1).attachments 

Este será conjunto de objetos apego

Utilice el método de selección para filtrar basado en file_type.

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

Esto no activará ninguna consulta db.

Cuestiones relacionadas