2012-04-09 22 views
71

So führe ich eine Anfrage an die db und ich habe eine komplette Reihe von Objekten:Rails Filtern Array von Objekten durch Attributwert

@attachments = Job.find(1).attachments 

Nun, da ich ein Array von Objekten habe ich möchte nicht ausführen ein weitere db-Abfrage, aber ich mochte das Array auf der Grundlage des Attachment Objekt file_type filtern, so dass ich eine Liste von attachments haben kann, wo der Dateityp 'logo' und dann eine andere Liste von attachments ist, wo der Dateityp 'image'

Etwas so:

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

Aber im Speicher statt einer DB-Abfrage.

Prost

Antwort

135

Versuchen:

Das ist in Ordnung:

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

aber für die Leistung weise Sie nicht brauchen @Attachments zweimal zu durchlaufen:

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

Da @ Viks Lösung ziemlich ideal ist, werde ich das nur in binären Fällen hinzufügen, Sie könnten eine "Partitions" -Funktion verwenden, um die Dinge süß zu machen. http://ruby-doc.org/core-1.9.3/Enumerable.html#method-i-partition – Vlad

+0

Dank @Vlad, das ist cool, aber es unterstützt nur, wenn wir nur zwei Dinge vom Objekt sammeln müssen. – Vik

+0

Ja, deshalb habe ich "binary" gesagt :). In der Frage gab es anscheinend eine Wahl von Logo oder Bild, also fügte ich das zur Vollständigkeit hinzu. – Vlad

2

haben Sie versucht, eifrig laden?

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

Leider habe ich nicht klar bin zu sein: wie filtere ich nach dem Wert eines Objektattributs, ohne das Array zu durchlaufen? – joepour

+0

Wenn ich richtig verstanden habe, wollen Sie weniger DB-Abfrage, vor allem, wenn eine Abfrage wie '@attachments = Job.first.attachments' ausgeführt wird, möchten Sie die' @ Anhänge' durchlaufen, während Sie keine weiteren Datenbankabfragen wünschen . willst du das machen? –

+0

Ich mache eine DB-Abfrage und empfange ein Array von Objekten. Ich möchte dann zwei separate Listen von diesem einen Array erstellen, indem ich die Objekte nach dem Wert ihrer Attribute filtere (siehe Originalbeitrag) - prost – joepour

3

Wenn Ihre Anlagen

@attachments = Job.find(1).attachments 

sind Dadurch wird der Befestigung sein Array

Verwenden select-Methode basiert auf file_type filtern Objekte.

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

Dies wird keine DB-Abfrage ausgelöst.

Verwandte Themen