
kontaktiere uns


Dieser Beitrag wurde ursprünglich veröffentlicht im Juli 2018 von Pedro Rolo und aktualisiert im Juni 2020 von Tiago Madeira .
Es gibt mehrere Funktionen, die Ruby on Rails attraktiv, aber wo es wirklich glänzt, ist, wenn es darum geht, Informationen aus relationalen Datenbanken abzurufen. Es ist ORM -
Aktiver Datensatz - bietet jetzt eine sehr ausgereifte Oberfläche, die das richtige Gleichgewicht zwischen Prägnanz und Leistung bietet.
In diesem Artikel werde ich einige einfache Beispiele dafür geben, wie Informationen aus einer Datenbank extrahiert werden können. Dies soll kein umfassender Leitfaden sein, sondern eine Reihe von Tools, die ich in meiner täglichen Arbeit als nützlich empfunden habe. Außerdem basiert das, was ich im Folgenden vorstelle, auf dem neuesten Rails-Update (Rails 6).
Ich beginne mit der Definition eines Domänenmodells, gegen das ich meine Abfragen ausführen werde:
In unseren Beispielen verwenden wir das folgende Domänenmodell:
Im Grunde Person
und Firma
gehören zu einem Land
, und Person
und Firma
eine Viele-zu-Viele-Beziehung zwischen ihnen haben, die in der Beziehungstabelle gespeichert ist Firma/Person
.
Das #activerecord
ist das, was das Modell in unserer Ruby-Anwendung an die jeweilige Datenbanktabelle bindet. Das Active Record-Objekt enthält eine Reihe von Methoden, mit denen wir Datenbankdatensätze abfragen können, sodass kein Roh-SQL verwendet werden muss. Zu Vergleichszwecken werde ich die Übersetzung unserer ActiveRecord-Abfragen in SQL-Abfragen vorstellen. Sie können diese Übersetzung einfach durchführen mit #to_sql
.
Die einfachsten Abfragen umfassen nur eine einzige Tabelle und versuchen, die Datensätze abzurufen, deren Spalten bestimmte Werte enthalten.
Nehmen wir zum Beispiel an, wir wollen herausfinden, wer John als Vornamen hat:
Wir können auch Arrays mit wünschenswerten Werten anstelle von Einzelwerten verwenden. Dadurch werden Abfragen generiert, die das verwenden IN
SQL-Schlüsselwort:
Zusätzlich zu Arrays werden Bereiche auch als Wertprädikate akzeptiert:
Sie können auch endlose Reichweiten haben:
was jetzt mit Rails 6 einfach so geschrieben werden kann:
Es ist möglich, unsere Abfragen auf mehrere gleichzeitige Prädikate zu beschränken. Wir können entweder #where
ein Hash mit mehreren Schlüsselwörtern oder wir können mehrere Aufrufe von verketten #where
:
Wenn wir unsere Prädikate anders zusammensetzen wollen mit einem ODER
wir können verwenden #or
.
Wenn wir nur nach einer bestimmten Zeile suchen, können wir verwenden #find_by
stattdessen, was die Suche beendet, sobald es den ersten Treffer gefunden hat, indem es GRENZE 1
Oder wir können unser eigenes benutzerdefiniertes Limit durch Verkettung festlegen #limit
zu unserem #where
Abfragen:
Es ist möglich, die Aufzeichnungen zu bekommen nicht übereinstimmend ein bestimmter Zustand durch die Verwendung von #not
zusammen mit #where
:
Es ist möglich zu verwenden #order
um die Ergebnisse in aufsteigender oder absteigender Reihenfolge zu sortieren:
Es gibt mehrere Funktionen, mit denen ein Abfrageergebnis in bestimmte Werte gegliedert werden kann, z. B. #count
, #maximum
, #minimum
und #average
:
Zusätzlich ist es möglich, Elemente nach einer bestimmten Spalte zu gruppieren und diese Elemente mit diesen Faltfunktionen zu falten, wodurch Folgendes ausgeführt wird GRUPPE_VON
Abfragen:
Der häufigste Anwendungsfall in Bezug auf mehrere Tabellen ist das eifrige Laden einiger Entitäten, die sich auf unser ausgewähltes Modell beziehen und auf die beispielsweise iterativ zugegriffen werden kann. Dieses Problem ist allgemein bekannt als Problem mit +1 N Abfragen
und das folgende Zusammenspiel macht es deutlich:
Wie wir sehen, wird jedes Mal, wenn wir eine Person wiederholen, um auf ihr Land zuzugreifen, eine neue Abfrage durchgeführt.
#includes
#includes
ermöglicht es uns, alle Daten auf einmal zu laden und so die oben genannten Aktionen zu optimieren. Es verhält sich wie ein LINKE ÄUSSERE VERBINDUNG
und lädt somit alle Einträge des zugehörigen Modells, die unsere Hauptmodelleinträge betreffen.
Aber warte, das ist kein LINKE ÄUSSERE VERBINDUNG
- könnte man sagen! Nun, da es für die Länder, die wir auswählen, keine zusätzlichen Einschränkungen gibt, greift Rails lieber auf WO ist DRIN
Abfrage, die den Primärschlüsselindex nutzt. Wenn wir unserer Abfrage jedoch Einschränkungen hinzufügen, führt der aktive Datensatz eine aus LINKE ÄUSSERE VERBINDUNG
stattdessen:
Was im obigen Beispiel zu beachten ist, ist die Verwendung eines Hashs für die Where-Bedingung, um Einschränkungen für unsere referenzierten Modelle zu spezifizieren.
Wir können auch eifrig mehrere Relationen gleichzeitig laden:
Und es ist auch möglich, dies verschachtelt zu tun, indem stattdessen ein Beziehungs-Hash übergeben wird:
#joins
Manchmal interessieren uns nur die Datensätze, die dem entsprechenden Modul zugeordnet sind. Wenn dies der Fall ist, verwenden wir #joins
, das die Semantik einer INNERES GELENK
.
Wir veranschaulichen die Notwendigkeit dieser Funktionalität im folgenden Beispiel, in dem wir nur Personen verwenden wollen, die tatsächlich mit einem Land in Verbindung stehen:
Wenn wir nur an Datensätzen interessiert sind, die einem verwandten Modell mit bestimmten Attributwerten zugeordnet sind, können wir verwenden #joins
und dann #where
um Einschränkungen für unsere Modelle zu spezifizieren.
Nun, alle bisher geschriebenen Anfragen sind ziemlich lang. Wenn sie kompliziert werden oder über unseren Code wiederverwendet werden sollen, ist es praktisch, ihnen Namen zu geben.
In älteren Versionen von Rails sollten Sie die Aktiver Datensatz:: Base #scope
Klassenmethode, um solche wiederverwendbaren Abfragen zu erstellen. Sie können dieselbe Funktionalität erreichen, indem Sie einfach Klassenmethoden definieren:
Nachdem Sie die Abfragen auf diese Weise definiert haben, können Sie diese Abstraktionen auf hoher Ebene miteinander verketten.
Arel ist eine domänenspezifische Sprache, mit der Sie Ihre Fragen in relationaler Algebra ausdrücken können. In früheren Versionen von Rails war es ziemlich üblich, auf Arel zurückgreifen zu müssen, um einige häufig nachgefragte Funktionen zu erfüllen, obwohl Active Record von Rails 6 heutzutage bereits die meisten dieser Anwendungsfälle abdeckt.
Ich werde zunächst einige der bereits vorgestellten Rails 6-Abfragen vorstellen, indem ich Arel anstelle von Plain Active Record verwende. Und später konzentriere ich mich darauf, wie man einige Fälle schreibt, in denen man Arel immer noch benötigen würde.
Beim Erstellen von Arel-Abfragen beginnt man normalerweise damit, Arel: :Tabelle
Objekte der SQL-Tabellen, mit denen wir interagieren wollen:
Wir können wie ein Hash auf die Spalten unserer Tabellen zugreifen. Aus diesen Tabellen kann man Prädikate definieren (Arel: :Knoten
) Aufrufen von Methoden für ihre Attribute, auf die über die Methode zugegriffen werden kann []
:
Die Prädikate #eq
, #not_eq
, #lt
, #gt
, #lteq
, #gteq
entsprechen den Operatoren =,! =, <, >, <=, >= und funktionieren wie folgt:
Das #and
& #or
kann verwendet werden, um Prädikate für mehrere Tabellen zu erstellen und auf ähnliche Weise zu arbeiten, wie folgt:
Wir können diese Prädikate später weitergeben an #where
, und solange die erforderlichen Tabellen verknüpft sind, wird das Prädikat erfolgreich in SQL konvertiert:
Dies ist ein Anwendungsfall, bei dem man immer noch auf Arel zurückgreifen muss, um eine datenbankunabhängige Abfrage zu erhalten. Um dies zu tun, sollte man die kombinieren #matches
Arel-Prädikat mit dem %
SQL-Platzhalter:
Dies gibt Personen zurück, deren Nachname mit dem Zeichen „A“ beginnt.
Sowohl Arel als auch Active Record haben viel mehr Funktionen als die, die ich hier vorgestellt habe. Sie sind jedoch mehr als genug, um mit Anwendungen mit einfachen Anforderungen zu beginnen.
Am Ende kommt es darauf an, bei unseren alltäglichen Abfragen zwischen ActiveRecord-Abfragemethoden oder Arel zu wählen. Ich finde die ActiveRecord-Syntax einfacher zu lesen und zu verwenden, aber Arel kann immer noch nützlich sein, wenn es um komplexe Abfragen geht.
Rails-Entwickler mit mehr als 10 Jahren Erfahrung mit verschiedenen Technologien. Ich interessiere mich für funktionale Programmierung.
Informatikstudent und Teilzeitbeschäftigter von Imaginary Cloud. Begierig darauf, neue Technologien und Techniken zu erlernen. Tennis- und Klavierspieler.
People who read this post, also found these interesting: