Ruby ist eine der beliebtesten Sprachen im Internet. Wir haben hier auf Nettuts + eine neue Session gestartet, die Sie in Ruby einführen wird, sowie die großartigen Frameworks und Tools, die mit der Ruby-Entwicklung einhergehen. Heute schauen wir uns die DataMapper-Gems an, um eine Datenbank in Ruby einzurichten.
DataMapper ist ein ORM: eine objektrelationale Zuordnung. Im Grunde handelt es sich dabei um eine Bibliothek, mit der Sie aus objektorientiertem Code mit Ihrer Datenbank arbeiten können. Es gibt absolut keine SQL in diesem Tutorial. Ein ORM verwendet jedoch eine reguläre Datenbank unter den Deckblättern. Wir werden heute sqlite3 verwenden, aber Sie könnten auch einen anderen Adapter verwenden, um mit einer MySQL-, Postgresql- oder einer anderen Datenbank zu arbeiten.
In Sinatra singen - The Recall App stellte Ihnen Dan Harper DataMapper vor. In diesem Tutorial werden wir tiefer in die Arbeit mit der Bibliothek eintauchen.
Der erste Schritt ist die Installation der benötigten Edelsteine. Die DataMapper-Funktion ist in viele verschiedene Edelsteine unterteilt, daher müssen Sie verschiedene Teile installieren. Natürlich werden wir nicht mit allem arbeiten; Dies sind jedoch die Edelsteine, die Sie installieren müssen.
dm-postgres-adapter
, dm-mysql-adapter
, oder was auch immer zu Ihnen passt.Wenn Sie alle Edelsteine installiert haben (siehe letztes Kapitel, wenn Sie wissen müssen, wie Sie Edelsteine installieren), können Sie loslegen.
Beginnen wir mit der Erstellung eines Basismodells. Modelle werden in Klassen definiert. Wir müssen jedoch zuerst eine Verbindung zu unserer Datenbank herstellen.
Eigentlich ist das allererste Erfordernis, dass unsere Bibliotheken ganz oben in unserer Datei stehen.
erfordern 'dm-core' erfordern 'dm-timestamps' erfordern 'dm-validations' erfordern 'dm-migration'
Jetzt, da wir DataMapper in der Umgebung haben, verbinden wir uns mit der Datenbank.
DataMapper.setup: Standardwert "sqlite: // # Dir.pwd /database.db"
Der erste Parameter weist DataMapper an, den Standardadapter für den Datenbanktyp zu verwenden. Der zweite ist der Link / die URL für die Datenbank. Da wir sqlite verwenden, verlinken wir lediglich auf eine Datenbankdatei. Beachten Sie, dass wir diese Datei nicht erstellen müssen. DataMapper erstellt es für uns.
Jetzt können wir das Modell erstellen. Wie Sie wissen, ist dies eine Klasse.
Klasse User include DataMapper :: Ressource-Eigenschaft: ID, Serielle Eigenschaft: Benutzername, String-Eigenschaft: E-Mail, String-Ende
Der erste Schritt besteht darin, die DataMapper :: Ressource
Modul. Dadurch erhalten Sie die benutzerdefinierten Methoden, die Sie in Ihrer Klasse verwenden. Die wichtigste Methode ist hier Eigentum
. Hier erstellen wir drei verschiedene Eigenschaften: eine ID, einen Benutzernamen und eine E-Mail. Wie Sie sehen, ist der erste Parameter in Eigentum
ist ein Symbol, das der Name der Eigenschaft ist. Der zweite ist der Typ. Sie verstehen natürlich String, aber was ist seriell? Tatsächlich, Eigenschaft: ID, Serial
ist DataMappers Abkürzung für den Primärschlüssel; 'serial' ist eine automatisch inkrementierende Ganzzahl. Das ist dein Primärschlüssel!
Nachdem wir unser Modell erstellt haben, müssen wir die Datenbank migrieren. Wenn Sie mit der Migration einer Datenbank nicht vertraut sind, ändern Sie das Schema der Datenbank. Dies kann das Hinzufügen einer Spalte, das Umbenennen einer Spalte oder das Ändern der Eigenschaften einer Spalte sein. DataMapper bietet zwei Möglichkeiten, dies zu tun:
DataMapper.auto_migrate! DataMapper.auto_upgrade!
Der Unterschied hier ist das auto_migrate!
löscht alle Daten aus der Datenbank; das auto_upgrade!
Methoden versucht, die bereits vorhandenen Änderungen in der Datenbank abzugleichen. Das funktioniert so, dass Sie nach Ihrer Modellklasse eine dieser Methoden aufrufen. Du willst nicht laufen auto_migrate!
natürlich jedes Mal, wenn Sie das Modell laden, aber Sie möchten vielleicht ausführen auto_upgrade!
bei jedem reload in der entwicklung. Ich habe es in Sinatra so gemacht:
configure: Entwicklung do DataMapper.auto_upgrade! Ende
Sie werden feststellen, dass wir bisher keine einzige SQL-Abfrage berühren mussten. Die Verwendung von ORM besteht darin, dass Sie normalen Code schreiben und mit relationalen Datenbanken arbeiten können.
Jetzt, da wir mit DataMapper nasse Füße haben, bringen wir unser Modell auf eine andere Ebene. Beginnen wir mit Zeitstempeln.
Wir brauchen die dm-Zeitstempel
Juwel, warum also nicht? Wenn wir dem Modell die Eigenschaften 'created_at' und 'updated_at' hinzufügen, werden diese Felder automatisch von diesem Edelstein aktualisiert.
property: created_at, DateTime-Eigenschaft: updated_at, DateTime
Natürlich müssen Sie nicht beide hinzufügen, wenn Sie sie nicht möchten.
Sie können jedem Feld mehrere Optionen hinzufügen. Wenn Sie beispielsweise möchten, dass ein Feld erforderlich oder eindeutig ist oder einen Standardwert hat, können Sie dies dort tun. Lassen Sie uns ein Post-Modell erstellen, um einige davon darzustellen:
Klasse Post include DataMapper :: Resource-Eigenschaft: slug, String, Schlüssel: true, unique_index: true, Standardwert: lambda | resource, prop | resource.title.downcase.gsub "", "-" property: title, String, erforderlich: true property: body, Text, required: true property: created_at, DateTime-Eigenschaft: updated_at, DateTime-Ende
Wir mischen hier ein bisschen auf; unser 'title' und 'body' sind Pflichtfelder. Wir definieren die Eigenschaft 'slug' als Primärschlüssel und sagen, dass es sich um einen eindeutigen Index handeln muss. Lassen Sie sich durch den Standardwert 'slug' nicht abschrecken. Natürlich können Sie einfach einen Rohwert für den jeweiligen Typ Ihrer Immobilie verwenden, aber wir tun etwas mehr. Ruby (und andere Sprachen) hat Lambdas, die man sich als kleine Funktion vorstellen kann. Es kann etwas sein, Parameter? und einen Wert zurückgeben, genau wie eine Funktion. Wenn wir ein Lambda als Wert für die 'default'-Eigenschaft verwenden, wird der DataMapper die Ressource (oder den Datenbankdatensatz, mit dem Sie arbeiten) und die Eigenschaft selbst (in diesem Fall' slug ') übergeben. Also nehmen wir hier den Wert ein resource.title
(die Titeleigenschaft), in Kleinbuchstaben und mit gsub
Methode (denken Sie Global Substitution), um jeden Raum in einen Strich zu verwandeln. Auf diese Weise etwa so:
"Dies ist ein Titel"
Wird das werden:
"Dies ist ein Titel"
Hinweis: Lassen Sie sich nicht damit verwirren, wie wir hier Optionen verwenden. Denken Sie zunächst daran, dass, wenn ein Hash der letzte Parameter einer Methode ist, die geschweiften Klammern nicht hinzugefügt werden müssen. Mit Ruby 1.9 gibt es außerdem eine neue Hash-Syntax. Zuvor sahen Hashes so aus:
: key => "value"
Sie können dies in 1.9 noch tun, und Sie müssen, wenn Sie keine Symbole als Schlüssel verwenden. Wenn Sie jedoch Symbole als Schlüssel verwenden, können Sie stattdessen Folgendes tun:
Schlüsselwert"
Im Grunde bewegen Sie einfach den Doppelpunkt an das Ende des Symbols (kein Leerzeichen!) Und entfernen die Rakete.
In DataMapper können Sie viel mit der Validierung tun, und Sie können hier alles darüber lesen. Schauen wir uns jedoch die Grundlagen an.
Es gibt zwei Möglichkeiten, Validierungen durchzuführen. Wir werden die Methode verwenden, die Ihre Validierungen dem Options-Hash hinzufügt. Für die E-Mail-Eigenschaft im Benutzermodell legen wir die Formatprüfung fest:
Eigenschaft: E-Mail, String, Format:: E-Mail-Adresse
In diesem Fall verwenden wir eine integrierte Regex, die DataMapper bietet. Wir könnten dort einen benutzerdefinierten Regex setzen, wenn wir etwas anderes wollen.
Lassen Sie uns eine bestimmte Länge des Passworts verlangen:
Eigenschaft: Passwort, String, Länge: 10? 255
Wenn Sie die 10 nicht kennen? 255 Notation, das ist ein Ruby-Bereich. Wir sagen, dass das Passwort zwischen 10 und 255 Zeichen lang sein muss.
Wie wäre es mit Fremdschlüsseln? DataMapper macht das ganz einfach. Lassen Sie uns unsere Benutzer- und Postmodelle verknüpfen. Wir möchten, dass ein Benutzer viele Beiträge haben kann und ein Beitrag zu einem Benutzer gehören kann.
Fügen Sie im Benutzermodell diese Zeile hinzu
hat n,: Beiträge
Führen Sie dann im Post-Modell Folgendes aus:
gehört_zu: Benutzer
In der Datenbank wird ein a hinzugefügt Benutzeridentifikation
Eigenschaft an einem Pfostentisch. In der Praxis ist das wirklich einfach. Wir werden das bald sehen.
Wenn Sie die Eingabe für eine bestimmte Eigenschaft anpassen möchten, können Sie benutzerdefinierte Eigenschafts-Accessoren hinzufügen. Angenommen, wir möchten sicherstellen, dass der Benutzername eines Benutzers immer in Kleinbuchstaben gespeichert wird. Wir können Eigenschaftszugriffsmethoden hinzufügen, die der einer normalen Klasse ähneln. Auf diese Weise nehmen wir den Wert, den der Benutzer zu speichern versucht, und korrigieren ihn. Lass uns das machen:
def username = new_username super new_username.downcase ende
Wir definieren das Benutzername =
, Wenn also der Benutzername vergeben wird, wird er als Kleinschreibung verwendet. Das Super
Teil gibt unseren Wert einfach an die Super-Methode dieser Methode weiter, die wir überschreiben.
Hinweis: Laut Dokumentation (siehe hier und hier) sollten wir dies können @username = neuer_benutzername.fallfall
in der obigen Methode. Das habe ich im Screencast gemacht, und wie Sie wissen, funktionierte es nicht wie erwartet. Seit der Aufnahme des Screencast habe ich festgestellt, dass die Dokumentation falsch ist Super
ist der Weg dies zu tun.
Nun, da unsere Modelle erstellt wurden, fügen wir ein paar Datensätze hinzu, um sie zu testen. Wir können dies auf verschiedene Arten tun. Zuerst können wir einen Datensatz mit erstellen Neu
Übergeben Sie einen Hash von Attributen oder weisen Sie sie einzeln zu.
user = User.new Benutzername: "JoeSchmo", Vorname: "Joe", Nachname: "Schmo", E-Mail: "[email protected]", Kennwort: "password_12345" user.save user = User.new user.username = "Andrew" # usw .. user.save
Beim Benutzen Benutzername # neu
, du musst das anrufen sparen
Methode, um den Datensatz tatsächlich in die Datenbank aufzunehmen. Wenn es einen Fehler gibt (erinnern Sie sich an diese Validierungen?), Die sparen
Methode gibt false zurück. Dann können Sie zum gehen Fehler
Eigenschaft, um die Fehler zu sehen; Es ist ein DataMapper :: Validations :: ValidationsErrors-Objekt, aber Sie können die Fehler mit dem iterieren jeder
Methode.
user.errors.each do | error | setzt Fehlerende
Wenn Sie einen Datensatz auf einen Schlag erstellen und speichern möchten, verwenden Sie die erstellen
Methode, natürlich ein Attribut Hash übergeben.
User.create Benutzername: "joeschmo", Vorname: "Joe", Nachname: "Schmo", E-Mail: "[email protected]", Passwort: "Passwort _! @ # $%"
Boom: erstellt und gespeichert!
Wie wäre es mit einem Datensatz in der Datenbank? Wenn Sie den Schlüssel des Datensatzes kennen, nach dem Sie suchen, verwenden Sie einfach die get-Methode:
User.get (1) Post.get ("Dies-ist-ein-Titel")
Ja, Sie sehen, dass dies sowohl mit normalen Integer-Schlüsseln als auch mit anderen Schlüsseltypen funktioniert. Da wir sagten, die Schnecke war der Schlüssel im Post
Modell können wir erhalten
durch die Schnecke.
Was ist mit den Feldern, die für mehrere Datensätze gleich sein könnten? Dafür haben Sie drei Möglichkeiten: die erste, die letzte und alle. Geben Sie ihnen einen Hash, und sie erhalten die Unterlagen für Sie
User.first vorname: "Andrew" User.last (: lastname => "Schmo") User.all #zielt alle Beiträge
Mit DataMapper können Sie noch viel mehr tun. Lesen Sie die Dokumentation für mehr! Klicken Sie auf das Fragenfeld, wenn Sie Fragen haben.