Wie kann ich diesen Code in unformatiertes SQL konvertieren und in Rails verwenden? Denn wenn ich diesen Code in Heroku bereitstelle, tritt ein Fehler beim Anforderungszeitlimit auf. Ich denke, dies wird schneller, wenn ich Raw SQL verwende.
@payments = PaymentDetail.joins(:project).order('payment_details.created_at desc')
@payment_errors = PaymentError.joins(:project).order('payment_errors.created_at desc')
@all_payments = (@payments + @payment_errors)
sql
ruby-on-rails
Johnny Cash
quelle
quelle
Antworten:
Du kannst das:
records_array
wäre dann das Ergebnis Ihrer SQL-Abfrage in einem Array, das Sie durchlaufen können.quelle
records_array
gibt verschiedene Typen für verschiedene Datenbankadapter. Wenn Sie PG verwenden, ist dies eine Instanz vonPG::Result
, nichtArray
.values
diesesPG::Result
Objekt aufrufen , um das Ergebnisarray zu erhaltenActiveRecord::Base.connection.exec_query
besser, weil es einActiveRecords::Result
Objekt zurückgibt, das praktische Methoden wie.columns
und.rows
für den Zugriff auf Header und Werte hat. Das Array von Hashes von.execute
kann schwierig zu handhaben sein und hat mir redundante Ergebnisse geliefert, wenn ich mit einer SUM GROUP BY-Klausel ausgeführt habe.Ich weiß, das ist alt ... Aber ich hatte heute das gleiche Problem und fand eine Lösung:
Wenn Sie die Ergebnisse instanziieren möchten:
Wenn Sie nur einen Hash von Werten wollen:
Ergebnisobjekt:
select_all
gibt einresult
Objekt zurück. Sie können damit magische Dinge tun.Quellen:
quelle
#find_by_sql
ist genau das, was ich wollte, vielen Dank.Sie können eine Rohabfrage mit ausführen
ActiveRecord
. Und ich werde vorschlagen, mit SQL-Block zu gehenquelle
SELECT * FROM users WHERE users.id = #{ user.id }
Sie können Direct SQL ausführen, um eine einzige Abfrage für beide Tabellen zu erhalten. Ich werde ein Beispiel für eine bereinigte Abfrage bereitstellen, um zu verhindern, dass Benutzer Variablen direkt in die Zeichenfolge selbst einfügen (SQL-Injection-Gefahr), obwohl in diesem Beispiel nicht angegeben wurde, dass dies erforderlich ist:
Edit : wie Huy sagte, ist ein einfacher Weg
ActiveRecord::Base.connection.execute("...")
. Ein anderer Weg istActiveRecord::Base.connection.exec_query('...').rows
. Sie können native vorbereitete Anweisungen verwenden, z. B. wenn Sie postgres verwenden. Die vorbereitete Anweisung kann mit raw_connection, prepare und exec_prepared ausgeführt werden, wie unter https://stackoverflow.com/a/13806512/178651 beschriebenSie können auch rohe SQL-Fragmente in relationale ActiveRecord-Abfragen einfügen : http://guides.rubyonrails.org/active_record_querying.html und in Zuordnungen, Bereichen usw. Sie könnten wahrscheinlich dasselbe SQL mit relationalen ActiveRecord-Abfragen erstellen und coole Dinge damit tun ARel als Ernie erwähnt in http://erniemiller.org/2010/03/28/advanced-activerecord-3-queries-with-arel/ . Und natürlich gibt es auch andere ORMs, Edelsteine usw.
Wenn dies häufig verwendet wird und das Hinzufügen von Indizes keine anderen Leistungs- / Ressourcenprobleme verursacht, sollten Sie einen Index in der Datenbank für payment_details.created_at und für success_errors.created_at hinzufügen.
Wenn viele Datensätze und nicht alle Datensätze gleichzeitig angezeigt werden müssen, sollten Sie die Paginierung verwenden:
Wenn Sie paginieren müssen, sollten Sie in der Datenbank zunächst eine Ansicht mit dem Namen "payment_records" erstellen, die die Tabellen "pay_details" und "payment_errors" kombiniert, und dann ein Modell für die Ansicht erstellen (das schreibgeschützt ist). Einige DBs unterstützen materialisierte Ansichten, was für die Leistung eine gute Idee sein könnte.
Berücksichtigen Sie auch Hardware- oder VM-Spezifikationen auf dem Rails-Server und dem DB-Server, die Konfiguration, den Speicherplatz, die Netzwerkgeschwindigkeit / -latenz usw., die Nähe usw. und erwägen Sie, die DB auf einem anderen Server / einer anderen VM als der Rails-App zu installieren, falls dies nicht der Fall ist .
quelle
Ich möchte mit
exec_query
derActiveRecord
Klasse arbeiten, da sie die Zuordnung der Abfrage zurückgibt, die in ein Objekt umgewandelt wird. Daher wird es sehr praktisch und produktiv, mit den Objekten zu iterieren, wenn das Subjekt Raw SQL ist.Beispiel:
und geben Sie diese vollständige Abfrage zurück:
Um nur eine Liste von Werten zu erhalten
Um nur Feldspalten zu erhalten
quelle
Sie können auch unformatiertes SQL mit ActiveRecord-Bedingungen mischen, z. B. wenn Sie eine Funktion in einer Bedingung aufrufen möchten:
quelle