2016-04-25 15 views
0

Ich bin auf einer Vereinigung eine find_by mit:Faking einem Datenbankeintrag für Active Record Methoden

"sub" eine viele zu einer Beziehung hat zu "main"

@main.subs.find_by(x: 123) 

in den meisten Fällen möchte ich diese zuzugreifen und aus der Datenbank eine „sub“ Rekord in Bezug auf „main“, mit einem normalen Auswahl abrufen:

select subs.* from subs where subs.main_id = 333 and subs.x = 123 

aber es gibt ein anderes Szenario, in dem ich es will, die Datenbank ignorieren und einen Stub ich zugreifen habe von "subs" erstellt unter „main“:

stub_sub = Sub.new(id: 22, x: 123, main_id: 333) 
@main.subs << stub_sub 

@main in der Datenbank entweder nicht gespeichert und wird erstellt, ebenso wie die Unter:

@main = Main.new(id: 333) 

wenn ich auf die find_by Linie beim Debuggen erhalten, und versuchen, access @ mains, es sieht aus wie eine aktive Datensatzbeziehung, die ich von einer DB-Abfrage bekommen würde, aber wenn ich etwas wie find_by/all mache, versucht es, auf die db zuzugreifen und zu sehen, dass dort nichts ist und eine leere Relation zurückgibt.

Gibt es eine Möglichkeit, find_by (oder eine andere aktive Record-Methode) am Zugriff auf die Datenbank zu hindern und nur an der Stub-Beziehung zu arbeiten, die ich dafür erstellt habe?

Antwort

0

Ich denke, es gibt ein paar Missverständnisse in Ihrer Frage dort. Erstens gibt die find_by Methode nicht alle übereinstimmende Datensätze, aber nur die first one, wahrscheinlich wollten Sie stattdessen die where Methode verwenden.

Zweitens, die << Betreiber auf einem has_many Verband tatsächlich saves the association record so eine where Abfrage zurückgegeben werden sollen perfekt nach der Vereinigung Zuordnung, das heißt kurz nach << Aufruf. Wenn das Hauptobjekt noch nicht in der Datenbank vorhanden ist, speichert der Operator << nichts. In diesem Fall ist die einzige Lösung, die mir in den Sinn kommt, ActiveRecord-Methoden (wie find_by oder where) aufzugeben, weil sie immer versuchen, die db abzufragen, um die Informationen zu erhalten und stattdessen manuell nach dem passenden verknüpften Datensatz zu suchen. erste, einschließlich der neu angeschlossene und nicht gespeicherten Einsen und dann filtern sie mit einem Rubin Zustand gegen ihre Attribute

@main.subs.to_a.select { |sub| sub.x == 123 } 

Auf diese Weise werden Sie alle angeschlossenen Verbände laden:

Also statt @main.subs.where(x: 123) Sie tun würden.

Der große Nachteil dabei ist jedoch, dass bei der Verwendung dieses Codes mit einem Datensatz gespeichert, werden Sie immer alle zugehörigen Datensätze laden, nicht nur diejenigen, die den Zustand entsprechen. Wenn Sie also einen Datensatz mit vielen verknüpften Datensätzen haben, würden Sie die Filterleistung beeinträchtigen.

+0

Die Frage wurde basierend auf dem von Ihnen angegebenen Link aktualisiert. Von dem, was ich dort sehe, würden die Subs gespeichert werden, wenn das Haupt auch ein Datensatz in der DB wäre, aber in meinem Fall ist es nicht .. Ich stosse alles von Grund auf neu und möchte Datenbankeinträge nachahmen, um abzurufen. – Poster

+0

OK, aktualisiert die Antwort. Noch eine Frage: Soll das in Tests verwendet werden? – BoraMa

+0

Nein, ich wünschte .. dann könnte ich einfach die find_by stubben und damit fertig sein. Ich muss nur find_by konditionieren und es nur ausführen, wenn ich nicht den Stub verwenden soll, da die meisten Male Datensätze aus der db abrufen sollen, im Gegensatz zu nicht, und stattdessen eine Art hardcoded verwenden Aufzeichnung. – Poster