2009-07-02 13 views
8

Ich frage mich, ob es eine effiziente Möglichkeit gibt, die Ergebnisse mehrerer ActiveRecord Objekte in Rails zu kombinieren. Zum Beispiel könnte ich drei individuelle Aufrufe an drei einzelne Tabellen machen, und ich möchte, dass die Ergebnisse kombiniert und nach einer gemeinsamen Spalte sortiert werden.Wie ActiveRecord Objekte zu kombinieren?

Hier ist ein super Grundcodebeispiel, das hoffentlich meine Frage machen wird leichter zu verstehen:

@results1 = Table1.find(:all) 
@results2 = Table2.find(:all) 
@results3 = Table3.find(:all) 

@combined_results_sorted_by_date_column = (how?) 

Wie bereits von anderen vorgeschlagen, hier ist eine Lösung für das Problem.

Was passiert, wenn ich nach Datum sortieren möchte, aber Tabelle3 verweist auf die Spalte "created_on" als Datum?

Antwort

2

Sie arbeiten nicht mit "Tabellen", sondern mit Objekten.

Wenn Sie es auf diese Weise denken, wäre es keinen Sinn zu haben, machen:

@results1 = Users.find(:all) 
@results2 = Posts.find(:all) 
@results3 = Comments.find(:all) 

Was wäre die „combined“ Form es bedeutet?

Was Sie wahrscheinlich wollen, ist, Ergebnisse der gleichen Art mit verschiedenen "Abfragen" zu kombinieren. Ist es das?

+0

Ich habe einen Usecase, kombinierte Kommentare, Status und Commits für eine Zeitleiste in einer Issue-Management-Anwendung. – dangerousdave

+0

In diesem Fall müssen sie alle auf eine bestimmte Schnittstelle antworten oder eine Möglichkeit haben, in eine solche zu mappen. Der entscheidende Punkt ist, dass das Nachdenken über "Datenbanktabellen" zu schlechten Designs führt. Ich wollte nicht implizieren, dass du keine Daten von verschiedenen Orten verwendest, sondern nur fragst, wie du darüber nachdenkst. –

0

Während dies sicherlich nicht der effizienteste Code der Welt ist, könnte es genau das sein, was Sie brauchen.

Wenn einige Modelle keine Datumsmethode haben, empfehle ich, eine zu erstellen. Es ist so einfach wie.

def date 
    created_on 
end 
0
@results1 = Table1.find(:all) 
@results2 = Table2.find(:all) 
@results3 = Table3.find(:all) 

combined = (@results1 + @results2 + @results3).sort { |x, y| x.date <=> y.date } 
+0

Was ist, wenn ich nach Datum sortieren möchte, aber Tabelle3 verweist auf die Spalte "created_on" als Datum? Vielen Dank! – Jess

+0

Sie könnten das lösen, indem Sie Table3 eine "date()" -Methode hinzufügen, die den Wert von "created_on" zurückgibt. – Ethan

14
@results1 = Table1.find(:all) 
@results2 = Table2.find(:all) 
@results3 = Table3.find(:all) 

@combined_results_sorted_by_date_column = 
    (@results1 + @results2 + @results3).sort_by(&:date) 

Was passiert, wenn ich nach dem Datum sortiert werden sollen, aber Table3 bezieht sich auf die "created_on" Spalte als Datum?

class Table3 
    alias_method :date, :created_on 
end 

oder einfach

class Table3 
    alias date created_on 
end 
0

Ich bin nicht sicher, was Ihre Datenmengen sind wie, aber wenn es um das Sortieren kommt, wird Ihre Datenbank einen besseren Job es tun, als Sie jemals mit " Anwendungsschicht "Code.

Benötigen Sie die zurückgegebenen Daten als ein Array von Modellobjekten, da die drei Tabellen wahrscheinlich ein gemischtes Array von drei verschiedenen Modellklassen generieren?

Warum nicht Direct-SQL verwenden Zeilen und Spalten zurückgeben und haben die DB die ganze Arbeit die Sortierung der Daten tun?

1

Sie werden diese Antwort wahrscheinlich nicht mögen, aber ich würde sagen, dass Sie vielleicht Ihr Datenbankschema überarbeiten möchten. Ich war in einer ähnlichen Situation und das Sortieren der Ergebnisse nach der Verkettung ist definitiv nicht die Art, wie Sie gehen wollen.

+1

Ich glaube dir, aber könnten Sie genauer sein, wie Sie die Situation behandelt haben? – iterion

0

Ich nehme an, Sie möchten ein gemischtes Array von drei verschiedenen Arten von ActiveRecord-Objekten, nach einem Datum sortiert.

@array = (Bucket.all + Mop.all + Detergent.all).sort{|x,y| x.sort_by <==> y.sort_by} 

Da Ihr sort_by-Feld für jeden Objekttyp unterschiedlich ist, müssen Sie es definieren.

class Bucket < ActiverRecord::Base 
    def sort_by 
    cleaned_on 
    end 
end 

class Detergent < ActiverRecord::Base 
    def sort_by 
    purchased_on 
    end 
end 

Sie konnten in allen Daten in einer einzigen Abfrage mit UNION sortiert ziehen, aber Sie würden nicht AR-Objekte aus, dass bekommen.

Verwandte Themen