Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Pedro Rolo
Tiago Madeira

Min Read

28. April 2021

Abfragen auf Rails - Active Record und Arel

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:

blue arrow to the left
Imaginary Cloud logo

Unser Domain-Modell

In unseren Beispielen verwenden wir das folgende Domänenmodell:

Domain Model


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.

blue arrow to the left
Imaginary Cloud logo

Was ist ActiveRecord

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.

ActiveRecord einfache Abfragen

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:


Zusammensetzbare ActiveRecord-Abfragen

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:

Negieren von Prädikaten

Es ist möglich, die Aufzeichnungen zu bekommen nicht übereinstimmend ein bestimmter Zustand durch die Verwendung von #not zusammen mit #where:


Sortierung

Es ist möglich zu verwenden #order um die Ergebnisse in aufsteigender oder absteigender Reihenfolge zu sortieren:


Gruppierung

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:


blue arrow to the left
Imaginary Cloud logo

ActiveRecord tritt bei

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.

Left Outer verbindet sich mit #includes

Left Outer Join Venn Diagram

#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 VERBINDUNGund 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:


Inner verbindet sich mit #joins

Inner Join Venn Diagram

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:


ActiveRecord-Verknüpfungen mit bestimmten Werten abfragen

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.

blue arrow to the left
Imaginary Cloud logo

Wiederverwendbare Abfrageabstraktionen mit Klassenmethoden

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.


blue arrow to the left
Imaginary Cloud logo

Was ist Arel

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.

Arel Tisch

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 []:

Arel einfache Abfrageprädikate

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:

Arel entspricht (SQL LIKE)

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.

blue arrow to the left
Imaginary Cloud logo

Fazit

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.

Ready for a UX Audit? Book a free call

Fanden Sie diesen Artikel hilfreich? Diese könnten dir auch gefallen!

blue arrow to the left
Imaginary Cloud logo
blue arrow to the left
Imaginary Cloud logo
blue arrow to the left
Imaginary Cloud logo
blue arrow to the left
Imaginary Cloud logo
blue arrow to the left
Imaginary Cloud logo
Pedro Rolo
Pedro Rolo

Rails-Entwickler mit mehr als 10 Jahren Erfahrung mit verschiedenen Technologien. Ich interessiere mich für funktionale Programmierung.

Read more posts by this author
Tiago Madeira
Tiago Madeira

Informatikstudent und Teilzeitbeschäftigter von Imaginary Cloud. Begierig darauf, neue Technologien und Techniken zu erlernen. Tennis- und Klavierspieler.

Read more posts by this author

People who read this post, also found these interesting:

arrow left
arrow to the right
Dropdown caret icon