<%= note.content %> "> [bearbeiten]
/ complete ">?
Erstellt: <%= note.created_at %>
Willkommen zu Track 2 des Singens mit Sinatra. Im ersten Teil haben wir Routen untersucht, wie mit URI-Parametern gearbeitet wird, wie mit Formularen gearbeitet wird und wie Sinatra Routen anhand der HTTP-Methode unterscheidet, von der sie angefordert wurden. Heute erweitern wir unser Wissen über Sinatra, indem wir eine kleine, datenbankgesteuerte App "Recall" zum Erstellen von Notizen / Erstellen einer Aufgabenliste erstellen.
Wir werden eine SQLite-Datenbank verwenden, um die Notizen zu speichern, und den DataMapper RubyGem verwenden, um mit der Datenbank zu kommunizieren. Führen Sie in einer Shell folgendes aus, um die relevanten Gems zu installieren:
gem installiere sqlite3 datamapper dm-sqlite-adapter
Je nachdem, wie Sie RubyGems auf Ihrem System eingerichtet haben, müssen Sie möglicherweise ein Präfix einfügen gem installieren
mit Sudo
.
Lassen Sie uns gleich loslegen, indem Sie ein neues Verzeichnis für das Projekt erstellen und die Anwendungsdatei erstellen, Rückruf.rb
. Beginnen Sie damit, indem Sie die entsprechenden Edelsteine anfordern:
erfordern 'rubygems' erfordern 'sinatra' erfordern 'datamapper'
Hinweis: Wenn Sie mit Ruby 1.9 arbeiten (was Sie sollten), können Sie die Zeile "Require 'rubygems" "löschen, da Ruby RubyGems trotzdem automatisch lädt.
Und richten Sie die Datenbank folgendermaßen ein:
DataMapper :: setup (: default, "sqlite3: // # Dir.pwd /recall.db") class Hinweis Beachten Sie, dass DataMapper :: Resource-Eigenschaft: id, Serielle Eigenschaft: content, Text,: required => true ist. complete, Boolean,: required => true,: default => false Eigenschaft: created_at, DateTime-Eigenschaft: updated_at, DateTime-Ende DataMapper.finalize.auto_upgrade!
In der ersten Zeile richten wir im aktuellen Verzeichnis eine neue SQLite3-Datenbank mit dem Namen Abruf.db
. Darunter bauen wir tatsächlich eine 'Notes'-Tabelle in der Datenbank auf.
Während wir die Klasse 'Note' nennen, erstellt DataMapper die Tabelle als 'Notes'. Dies entspricht einer Konvention, die Ruby on Rails und andere Frameworks und ORM-Module befolgen.
Innerhalb der Klasse richten wir das Datenbankschema ein. Die 'Notes'-Tabelle enthält 5 Felder. Ein Ich würde
Feld, das ein Ganzzahl-Primärschlüssel ist und automatisch inkrementiert wird ("Serial"). EIN Inhalt
Feld, das Text enthält, ein Boolean Komplett
Feld und zwei Datums- / Uhrzeitfelder, hergestellt in
und aktualisiert am
.
Die letzte Zeile weist DataMapper an, die Datenbank automatisch so zu aktualisieren, dass sie die von uns festgelegten Tabellen und Felder enthält, und dies erneut zu tun, wenn Änderungen am Schema vorgenommen werden.
Nun erstellen wir unsere Homepage:
Oben befindet sich ein Formular zum Hinzufügen einer neuen Notiz. Darunter befinden sich alle Notizen in der Datenbank. Fügen Sie der Anwendungsdatei zunächst Folgendes hinzu, Rückruf.rb
:
get '/' do @notes = Note.all: .order =>: id.desc @title = 'All Notes' erb: home end
Wichtige Notiz: Entferne den Punkt ('.
') im :.Auftrag
. (WordPress stört das Codebeispiel.)
In der zweiten Zeile sehen Sie, wie wir alle Notizen aus der Datenbank abrufen. Wenn Sie ActiveRecord (das in Rails verwendete ORM) verwendet haben, wird die Syntax von DataMapper sehr vertraut sein. Die Notizen sind der zugeordnet @Anmerkungen
Instanzvariable. Es ist wichtig, Instanzvariablen zu verwenden (das sind Variablen, die mit einem beginnen.) @
), so dass sie von der Ansichtsdatei aus zugänglich sind.
Wir setzen die @Titel
Instanzvariable, und laden Sie die Ansichten / home.erb
Datei über den ERB-Parser anzeigen.
Erstellen Sie die Ansichten / home.erb
Datei ansehen und mit folgendem Befehl beginnen:
<% # display notes %>
Wir haben ein einfaches Formular, das POST auf die Homepage ('/'
) und darunter ist ein ERB-Code, der jetzt als Platzhalter dient.
Der HTML-Standardwert unter Ihnen hat möglicherweise einen geringfügigen Schlaganfall erlitten, nachdem festgestellt wurde, dass unsere Home-View-Datei keinen Doctype oder andere HTML-Tags enthält. Nun, dafür gibt es einen Grund. Ein ... kreieren layout.erb
Datei in Ihrem Ansichten /
Verzeichnis, das Folgendes enthält:
<%= @title + ' | Recall' %> Erinnern
Weil Sie zu beschäftigt sind, um sich daran zu erinnern
<%= yield %>
Die zwei interessanten Teile sind hier die Zeilen 5 und 18. In Zeile 5 sehen Sie die erste Verwendung der <%=? %>
ERB-Tags. <%=
unterscheidet sich vom gewöhnlichen <%
wie es druckt was drin ist. Also hier zeigen wir das, was im ist @Titel
Instanzvariable gefolgt von | Erinnern
für die Seite
Etikett.
In Zeile 18 steht <%= yield %>
. Sinatra zeigt dies an layout.erb
Datei auf allen Routen. Und der tatsächliche Inhalt für diese Route wird an jeder beliebigen Stelle eingefügt Ausbeute
ist. Ausbeute
ist ein Begriff, der im Wesentlichen bedeutet "hier aufhören, einfügen, was wartet, dann weiter".
Starten Sie den Server mit Schrotflinteückruf.rb
in der Shell und schauen Sie sich die Startseite im Browser an. Sie sollten Inhalt aus der Layoutdatei und das Formular aus der tatsächlichen Datei anzeigen home.erb
Aussicht.
In die Layoutdatei haben wir zwei CSS-Dateien eingefügt. Sinatra kann statische Dateien (z. B. CSS, JS, Bilder usw.) aus einem Ordner mit dem Namen laden Öffentlichkeit/
im Wurzelverzeichnis. Erstellen Sie dieses Verzeichnis und darin zwei Dateien: reset.css
und style.css
. Der Reset enthält den HTML5-Boilerplate-CSS-Reset:
/ * HTML5? Boilerplate style.css enthält ein Reset, eine Normalisierung der Schriftart und einige Basisstile. Guthaben verbleibt, wenn Guthaben fällig ist. Viele Inspirationen wurden von diesen Projekten übernommen: yui.yahooapis.com/2.8.1/build/base/base.css camendesign.com/design/ praegnanz.de/weblog/htmlcssjs-kickstart * / / * html5doctor.com Stylesheet zurücksetzen ( Eric Meyers Reset Reloaded + HTML5-Baseline) v1.6.1 2010-09-17 | Autoren: Eric Meyer & Richard Clark html5doctor.com/html-5-reset-stylesheet/ * / html, body, div, span, Objekt, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre , abbr, adresse, zitieren, code, dfn, em, img, ins, kbd, q, samp, klein, stark, sub, sup, var, b, dl, dt, dd, ol, ul, li , fieldset, formular, beschriftung, legende, tabelle, beschriftung, tbody, tfoot, thead, tr, th, td, artikel, beiseite, leinwand, details, figcaption, abbildung, fußzeile, header, hgroup, menü, nav, abschnitt, zusammenfassung , Zeit, Marke, Audio, Video Marge: 0; Polsterung: 0; Grenze: 0; Schriftgröße: 100%; font: erben; vertikal ausrichten: Grundlinie; Artikel, beiseite, Details, Abb., Abbildung, Fußzeile, Kopfzeile, Gruppe, Menü, Navi, Abschnitt Anzeige: Block; blockquote, q Anführungszeichen: keine; blockquote: before, blockquote: after, q: before, q: after content: "; content: none; ins background-color: # ff9; color: # 000; text-decoration: none; mark background -color: # ff9; color: # 000; font-style: italic; font-weight: fett; del text-decoration: line-through; abbr [title], dfn [title] border-bottom: 1px gepunktet; Cursor: help; table border-collapse: collapse; border-spacing: 0; hr display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; Eingabe, wählen Sie vertical-align: middle; / * END RESET CSS * / / * für die Normalisierung der Schriftart, die von YUI Librarys fonts.css inspiriert wurde: developer.yahoo.com/yui/ * / body font : 13px / 1.231 sans-serif; * font-size: small; / * hack wird beibehalten, um die Spezifität zu erhalten * / select, input, textarea, button font: 99% sans-serif; / * Normalisierung der Monospace-Dimensionierung * en. wikipedia.org/wiki/MediaWiki_talk:Common.css/Archive_11#Teletype_style_fix_for_Chrome * / pre, Code, kbd, Samp Schriftfamilie: Monospace, Sans-Serif; / * * minimal b ase styles * / body, select, input, Textbereich / * # 444 sieht besser aus als schwarz: twitter.com/H_FJ/statuses/11800719859 * / color: # 444; / * Setze hier deine Basisschrift, um sie gleichmässig anzuwenden * / / * Schriftfamilie: Georgia, serif; * / / * -Header (h1, h2 usw.) haben keine Standardschriftgröße oder -rand. definieren Sie diese selbst. * / h1, h2, h3, h4, h5, h6 font-weight: fett; / * erzwinge immer eine Bildlaufleiste in Nicht-IE: * / html overflow-y: scroll; / * erreichbare Fokusbehandlung: people.opera.com/patrickl/experiments/keyboard/test * / a: hover, a: active Gliederung: keine; a, a: aktiv, a: besucht color: # 607890; a: hover color: # 036; ul, ol margin-left: 2em; ol list-style-type: dezimal; / * Ränder für Navigationslisten entfernen * / nav ul, nav li margin: 0; Listenstil: keine; list-style-image: keine; klein Schriftgröße: 85%; stark, th font-weight: fett; td vertikal-align: top; / * set sub, sup ohne Auswirkungen auf die Zeilenhöhe: gist.github.com/413930 * / sub, sup font-size: 75%; Zeilenhöhe: 0; Position: relativ; sup top: -0.5em; sub bottom: -0.25em; pre / * www.pathf.com/blogs/2008/05/formatting-quoted-code-in-blog-posts-css21-white-space-pre-wrap/ * / white-space: pre; Leerraum: Pre-Wrap; Leerraum: Vorzeile; Zeilenumbruch: Break-Word; Polsterung: 15px; textarea overflow: auto; / * www.sitepoint.com/blogs/2010/08/20/ie-remove-textarea-scrollbars/ * / .ie6 Legende, .ie7 Legende Rand links: -7px; / * thnx ivannikolic! * / / * Richten Sie die Checkboxen, Radios und Texteingaben mit ihrem Label an: Thierry Koblentz tjkdesign.com/ez-css/css/base.css * / input [type = "radio"] vertical-align: text-bottom; input [type = "checkbox"] vertical-align: bottom; .ie7 input [type = "checkbox"] vertical-align: baseline; .ie6 input vertikal-align: text-bottom; / * Handcursor auf anklickbare Eingabeelemente * / label, Eingabe [Typ = "Schaltfläche"], Eingabe [Typ = "Senden"], Eingabe [Typ = "Bild"], Schaltfläche Cursor: Zeiger; / * Webkit-Browser fügen einen Rand von 2px außerhalb des Formels von Formularelementen hinzu * / button, Eingabe, Auswahl, Textbereich margin: 0; / * Farben für Formulargültigkeit * / Eingabe: gültig, Textbereich: gültig Eingabe: ungültig, Textbereich: ungültig Randradius: 1px; -moz-box-shadow: 0px 0px 5px rot; -webkit-box-shadow: 0px 0px 5px rot; Box-Schatten: 0px 0px 5px rot; .no-boxshadow Eingabe: ungültig, .no-boxshadow Textbereich: ungültig Hintergrundfarbe: # f0dddd; / * Diese Auswahldeklarationen müssen getrennt sein. Kein Textschatten: twitter.com/miketaylr/status/12228805301 Außerdem: Pink. * / :: - moz-selection background: # FF5E99; Farbe: #fff; Text-Schatten: keiner; :: selection background: # FF5E99; Farbe: #fff; Text-Schatten: keiner; / * j.mp/webkit-tap-highlight-color * / a: link -webkit-tap-highlight-color: # FF5E99; / * Die Schaltflächen lassen sich im IE gut abspielen: www.viget.com/inspire/styling-the-button-element-in-internet-explorer/ * / button width: auto; Überlauf: sichtbar; / * bicubic Größenänderung für nicht-native IMG: code.flickr.com/blog/2008/11/12/on-ui-quality-the-little-things-client-side-image-resizing/ * / .ie7 img -ms-interpolation-mode: bikubisch;
Und style.css
enthält ein paar grundlegende Stylings, um die App hübsch aussehen zu lassen:
body margin: 35px auto; Breite: 640px; header text-align: center; Marge: 0 0 20px; header h1 display: inline; Schriftgröße: 32px; header h1 a: link, header h1 a: besuchte color: # 444; Textdekoration: keine; header h2 font-size: 16px; Schriftstil: kursiv; Farbe: # 999; #main margin: 0 0 20px; #add margin: 0 0 20px; #add textarea height: 30px; Breite: 510px; Polsterung: 10px; Rahmen: 1px fest #ddd; #add input height: 50px; Breite: 100px; Marge: -50px 0 0; Rahmen: 1px fest #ddd; Hintergrund: weiß; #edit textarea height: 30px; Breite: 480px; Polsterung: 10px; Rahmen: 1px fest #ddd; #edit input [type = submit] Höhe: 50px; Breite: 100px; Marge: -50px 0 0; Rahmen: 1px fest #ddd; Hintergrund: weiß; #edit input [type = Ankreuzfeld] height: 50px; Breite: 20px; article border: 1px solid #eee; Rand oben: keine; Polsterung: 15px 10px; article: first-of-type border: 1px fest #eee; article: nth-child (gerade) background: #fafafa; article.complete background: # fedae3; Artikelspanne font-size: 0.8em; p Marge: 0 0 5px; .meta font-size: 0.8em; Schriftstil: kursiv; Farbe: # 888; .links font-size: 1.8em; Zeilenhöhe: 0.8em; schweben rechts; Marge: -10px 0 0; .links a display: block; Textdekoration: keine;
Aktualisieren Sie die Seite in Ihrem Browser und alles sollte mehr gestylt werden. Machen Sie sich nicht zu viele Gedanken über dieses CSS. es sieht einfach nur ein bisschen schöner aus!
Wenn Sie jetzt versuchen, das Formular auf der Homepage zu senden, wird ein Routenfehler angezeigt. Lassen Sie uns jetzt die POST-Route für die Homepage erstellen:
post '/' do n = Note.newn.content = params [: content] n.created_at = Time.now n.updated_at = Time.now n.save umleiten '/' end
Wenn also eine Post-Anfrage auf der Homepage erfolgt, erstellen wir ein neues Note-Objekt in n
(Danke an den DataMapper ORM, Hinweis.neu
repräsentiert eine neue Zeile in der Anmerkungen
Tabelle in der Datenbank). Das Inhalt
Feld wird auf die übermittelten Daten aus dem Textbereich und dem Feld gesetzt hergestellt in
und aktualisiert am
datetime-Felder werden auf den aktuellen Zeitstempel gesetzt.
Die neue Notiz wird dann gespeichert und der Benutzer wird zur Startseite zurückgeleitet, auf der die neue Notiz angezeigt wird.
Wir haben also eine neue Notiz hinzugefügt, die wir aber noch nicht auf der Homepage sehen können, da wir den Code dafür nicht geschrieben haben. In der Ansichten / home.erb
Datei anzeigen, ersetzen Sie das <%# display notes %>
Zeile mit:
<% @notes.each do |note| %>> <% end %><%= note.content %> "> [bearbeiten]
/ complete ">?
Erstellt: <%= note.created_at %>
In der ersten Zeile beginnen wir eine Schleife durch jedes der @Anmerkungen
(alternativ hätten wir schreiben können für Hinweis in @Notes
, Die Verwendung eines Blocks, wie wir hier sind, ist jedoch eine bessere Praxis. In Zeile 2 geben wir die eine Klasse von
Komplett
wenn die aktuelle Note auf eingestellt ist Komplett
. Der Rest sollte ziemlich geradlinig sein.
So können wir Notizen hinzufügen und anzeigen. Jetzt brauchen wir nur noch die Möglichkeit, sie zu bearbeiten und zu löschen.
Das haben Sie vielleicht bei uns bemerkt home.erb
sehen wir ein [bearbeiten]
Verknüpfen Sie für jede Notiz das Wesentliche /:Ich würde
, Lass uns jetzt diese Route erstellen:
get '/: id' do @note = Note.get params [: id] @title = "Notiz bearbeiten params [: id]" erb: edit end
Wir rufen die angeforderte Notiz mit der angegebenen ID aus der Datenbank ab und richten ein @Titel
Variable und laden Sie die Ansichten / edit.erb
Datei über den ERB-Parser anzeigen.
Geben Sie Folgendes für das ein Ansichten / edit.erb
Aussicht:
<% if @note %>
/ löschen "> löschen
<% else %>Hinweis nicht gefunden.
<% end %>Dies ist eine ziemlich einfache Ansicht. Ein Formular, das auf die aktuelle Seite verweist, ein Textfeld mit dem Inhalt der Notiz und ein Kontrollkästchen, das aktiviert wird, wenn die Notiz auf festgelegt ist Komplett
.
Aber schau dir die dritte Zeile an. Geheimnisvoll Um dies zu erklären, müssen wir ein wenig auf die Spur bringen.
Sie haben von den beiden Begriffen GET und POST gehört.
Aber GET und POST sind nicht die einzigen "HTTP-Verben" - zwei weitere sollten Sie kennen: PUT und DELETE.
Technisch gesehen sollte der POST nur zum Erstellen von etwas verwendet werden, z. B. zum Erstellen einer neuen Notiz in Ihrer großartigen neuen Web-App.
PUT ist das Verb, um etwas zu ändern. Und DELETE, Sie haben es erraten, dient dazu, etwas zu löschen.
Mit diesen vier Verben können Sie eine App gut voneinander trennen. Es ist logisch. Leider unterstützen Webbrowser eigentlich keine PUT- oder DELETE-Anforderungen. Aus diesem Grund haben Sie wahrscheinlich noch nie davon gehört.
Um hier wieder auf Kurs zu kommen, wenn wir unsere App logisch aufteilen möchten (was Sinatra ermutigt), müssen wir diese PUT- und DELETE-Anforderungen fälschen. Sie werden unser Formular sehen Aktion
ist eingestellt auf Post
. Der Versteckte _Methode
Eingabefeld, auf das wir eingestellt haben stellen
In der dritten Zeile kann Sinatra diese PUT-Anfrage fälschen, während tatsächlich ein POST verwendet wird. In ähnlicher Weise verhalten sich Rails unter anderem.
Jetzt haben wir unsere PUT-Anfrage gefälscht, und wir können eine Route dafür erstellen:
put '/: id' do n = Note.get params [: id] n.content = params [: content] n.complete = params [: complete]? 1: 0 n.updated_at = Time.now n.save umleiten '/' end
Es ist alles ziemlich einfach. Wir erhalten den entsprechenden Hinweis mithilfe der ID in der URI, setzen die Felder auf die neuen Werte, speichern und leiten die Startseite um. Beachten Sie, wie wir in der vierten Zeile einen ternären Operator zum Setzen verwenden n.pl
zu 1
ob params [: komplettieren]
existiert oder 0
Andernfalls. Dies liegt daran, dass der Wert eines Kontrollkästchens nur dann mit einem Formular übermittelt wird, wenn es markiert ist. Wir prüfen also nur, ob es vorhanden ist.
In unserer edit.erb
In dieser Ansicht haben wir einen Link 'Löschen' zu dem Pfad hinzugefügt /: id / delete
. Fügen Sie dies Ihrer Bewerbungsdatei hinzu:
get '/: id / delete' do @note = Note.get params [: id] @title = "Löschen des Hinweises ## params [: id]" erb: delete beendet
Auf dieser Seite erhalten Sie vom Benutzer die Bestätigung, dass Sie diese Notiz tatsächlich löschen möchten. Erstellen Sie die Ansichtsdatei unter Ansichten / delete.erb
mit den folgenden:
<% if @note %><% else %>Möchten Sie die folgende Notiz wirklich löschen: "<%= @note.content %>"?
Hinweis nicht gefunden.
<% end %>Beachten Sie das, genau wie wir eine PUT-Anfrage gefälscht haben, indem Sie eine verborgene setzen _Methode
Eingabefeld, fälschen wir jetzt eine DELETE-Anfrage.
Ich bin sicher, dass Sie jetzt den Dreh raus haben. Die Löschroute lautet:
delete '/: id' do n = Note.get params [: id] n.destroy umleiten '/' end
Versuch es! Sie sollten jetzt Notizen anzeigen, hinzufügen, bearbeiten und entfernen können. Es gibt nur noch eine Sache?
Jetzt, wenn Sie eine Notiz als festlegen möchten Komplett
Sie müssen in die Bearbeitungsansicht gehen und das Kontrollkästchen auf dieser Seite aktivieren. Lassen Sie uns diesen Prozess etwas einfacher machen.
Als wir die Hauptseite eingerichtet haben, haben wir a /: id / complete
Link zu jeder Notiz. Lassen Sie uns jetzt diese Route erstellen, die einfach eine Note als vollständig (oder unvollständig, wenn sie bereits abgeschlossen ist) festlegt:
get '/: id / complete' do n = Note.get Parameter [: id] n.complete = n.complete? 0: 1 # Flip it n.updated_at = Time.now n.save Umleitung '/' beenden
Sie und Sinatra ziehen ein knackendes Duett ab! Sie haben sehr schnell eine einfache Web-App geschrieben, die alle CRUD-Vorgänge ausführt, die Sie von einer App erwarten würden. Es ist in super-sexy-clean-Ruby-Code geschrieben und in seine logischen Teile unterteilt.
Im letzten Teil von Singing with Sinatra, dem Encore, verbessern wir die Fehlerbehandlung, sichern die App von XSS und erstellen einen RSS-Feed für die Notizen.
Hinweis: Sie können die endgültigen Projektdateien für dieses Lernprogramm in GitHub durchsuchen.