German (Deutsch) translation by Władysław Łucyszyn (you can also view the original English article)
Zweimal im Monat besuchen wir einige der Lieblingsbeiträge unserer Leser aus der Geschichte von Nettuts +. Dieses Tutorial wurde erstmals im Januar 2010 veröffentlicht.
Gib mir eine Stunde deiner Zeit, und ich werde dich auf dem Ruby on Rails-Framework mitnehmen. Wir erstellen Controller, Modelle, Ansichten, fügen Admin-Logins hinzu und verteilen sie mit dem Heroku-Service in weniger als einer Stunde! In diesem Artikel erstellen wir eine einfache Bücherregal-Anwendung, in der Sie Bücher hinzufügen und Gedanken darüber schreiben können. Dann werden wir die Anwendung in nur wenigen Minuten bereitstellen. Also schnall dich an, denn dieser Artikel bewegt sich schnell!
In diesem Artikel wird davon ausgegangen, dass Sie möglicherweise wissen, was Ruby on Rails ist, aber nicht genau, wie es funktioniert. Dieser Artikel beschreibt nicht ausführlich, wie jeder Schritt funktioniert, aber er beschreibt, was wir tun müssen, und dann den Code, um das zu tun.
Null
Ruby on Rails ist ein Full-Stack-MVC-Webanwendungsframework. Full Stack bedeutet, dass Sie alles bekommen: einen einfachen Webserver, mit dem Sie Ihre Apps testen können, eine Datenbankschicht, ein Testframework und ein MVC-basiertes Design. MVC steht für Model-View-Controller.
Modell
Ein Modell speichert Informationen. Modelle werden in der Datenbank gespeichert. Rails unterstützt MySQL, PostgreSQL oder SQLite. Jedes Modell hat seine eigene Klasse und Tabelle. Sagen wir, wir wollen ein "Spiel" modellieren. Ein Spiel hat Dinge wie die Anzahl der Spieler, eine Startzeit, Endzeit, Mannschaften und einen Gewinner. Diese Attribute werden zu Spalten in der Tabelle "Spiele". Tabellennamen sind kleingeschrieben, unterstrichen und plural. Der Klassenname des Modells lautet "Spiel". In Rails erstellen Sie Modelle über Migrationen und Generatoren. Eine Migration beschreibt das Hinzufügen / Entfernen von Spalten und Tabellen aus der Datenbank.
Regler
Ein Controller ist der Manager. Es braucht Informationen und macht einige Logik wie CRUD, oder vielleicht ein paar Sachen aus einer Datei importieren, Berechtigungen hinzufügen / entfernen - Sie nennen es einen Controller kann es tun. Controller sind der Teil Ihrer App, der dies tut. Wie rufen wir Controller an? Schienen verwendet Routen. Eine Route ist eine formatierte URL, die an eine Aktion mit einer Reihe von Parametern gebunden ist. Um zum Game-Modell zurückzukehren, benötigen wir einen Controller für die Funktionalität. Irgendwann werden wir alle Spiele im System auflisten müssen. Eine grundlegende REST-URL für diese Route sieht wie "/ Spiele" aus. Woher weiß Rails, welcher Controller gesucht und welche Aktion aufgerufen werden soll? Es schaut auf Ihre routes.rb-Datei. Möglicherweise haben Sie eine Route, die wie folgt aussieht: "GET / macht {: name => 'games',: action => 'index'"}. Dies führt zu GamesController und seiner Indexmethode. Genau wie Modelle sind Klassennamen CamelCase und Dateinamen sind unterstrichen. Also würde unser GamesController in /app/controllers/games_controller.rb gespeichert werden. Nach der Logik rendert der Controller eine Ansicht.
Aussicht
Ein Blick ist der einfachste Teil, den man verstehen kann. Es ist was du siehst. Es ist der HTML-Code, den Sie generieren, um dem Benutzer anzuzeigen, was er benötigt. Ansichten sind ERB-Vorlagen. ERB steht für Embedded Ruby. Sie verwenden ERB ähnlich wie Sie PHP in ein Dokument einbetten. Wenn Sie eine Instanzvariable @ game.time in einen HTML-Code einfügen möchten, schreiben Sie <% = @ game.time%>
Zehn
Installieren Sie zuerst Rails. Installation von Rails ist je nach Plattform sehr einfach. Wenn Sie unter Linux / OSX arbeiten, ist das kein Problem. Windows ist komplizierter und ich habe keine Erfahrung damit. Dieser Abschnitt gibt Ihnen einen kurzen Überblick über die Installation von Rails über RubyGems, den Ruby-Paket-Manager. Ein Juwel ist ein Bündel Ruby-Code in einem Paket, das in Ihren Programmen verwendet werden kann. Installieren Sie für UNIX-basierte Systeme RubyGems, und installieren Sie das Rails-Juwel. Dieser Prozess wird etwa so aussehen:
1 |
|
2 |
# ubuntu
|
3 |
sudo apt-get install rubygems |
4 |
# fedora
|
5 |
sudo yum install rubygems |
6 |
# gentoo
|
7 |
sudo emerge rubygems |
8 |
# OSX
|
9 |
sudo port install rubygems |
10 |
|
11 |
# after you have rubygems installed
|
12 |
sudo gem install gemcutter # ruby gem hosting service |
13 |
sudo gem tumble |
14 |
sudo gem install Rails |
Hier finden Sie einige Links, die Sie beim Setup unterstützen
- Instant Rails, wie Instant LAMP aber für Rails
- Ubuntu Community Docs über Ruby on Rails
- Rails unter Windows laufen lassen
- Snow Leopard on Rails von einem Kerl, den ich kenne
- Der obligatorische Google Link
Sobald Sie den Befehl "Rails" ausführen können, sind Sie bereit für den nächsten Schritt.
Fünfzehn
Jetzt ist es an der Zeit, die Datenbankunterstützung zu installieren, bevor wir anfangen. Rails hat Unterstützung für alle gängigen DBs, aber für dieses Beispiel verwenden wir SQLite, weil es leichtgewichtig ist. Abhängig von Ihrer Plattform (wieder) kann die Installation von sqlite-Unterstützung einfach oder schmerzhaft sein. Es kann ein Schmerz sein, da der Edelstein gegen C-Erweiterungen gebaut werden muss, was bedeutet, dass das sqlite3-Paket auf Ihrem System installiert werden muss. Auch hier wird der Prozess in etwa so aussehen:
1 |
|
2 |
# ubuntu
|
3 |
sudo apt-get install sqlite3 sqlite3-devel |
4 |
# fedora
|
5 |
sudo yum install sqlite3 sqlite3-devel |
6 |
# OSX
|
7 |
sudo port install sqlite3 |
8 |
|
9 |
# then once you have the sqlite3 package installed
|
10 |
sudo gem install sqlite3-ruby |
Lesen Sie die vorherigen Links, wenn Sie Probleme mit diesen Schritten haben. Sie beschreiben auch die Installation von sqlite.
Zwanzig
Zeit, um unsere App zu generieren. Der Befehl rails erstellt eine Basisanwendungsstruktur. Alles, was wir tun müssen, ist in einem Verzeichnis zu sein und es so auszuführen:
1 |
|
2 |
$ cd ~/projects |
3 |
$ Rails bookshelf #this will create a new directory named bookshelf that holds our app |
4 |
$ cd bookshelf |
Es ist wichtig zu beachten, dass der Rails-Standard eine SQLite-basierte App ist. Du denkst vielleicht, was, wenn ich das nicht will? Der Befehl rails ist ein Generator. Es kopiert nur gespeicherte Dateien in ein neues Verzeichnis. Standardmäßig werden sqlite3-Datenbanken in /bookshelf/db/development.sqlite3, /bookshelf/db/production.sqlite3 und /bookshelf/db/testing.sqlite3 erstellt. Datenbankverbindungsinformationen sind in /bookshelf/config/database.yml gespeichert. Sie müssen diese Datei nicht bearbeiten, da sie Standardinformationen für ein SQLite-Setup enthält. Es sollte so aussehen:
1 |
|
2 |
# SQLite version 3.x
|
3 |
# gem install sqlite3-ruby (not necessary on OS X Leopard)
|
4 |
development: |
5 |
adapter: sqlite3 |
6 |
database: db/development.sqlite3 |
7 |
pool: 5 |
8 |
timeout: 5000 |
9 |
|
10 |
# Warning: The database defined as "test" will be erased and
|
11 |
# re-generated from your development database when you run "rake".
|
12 |
# Do not set this db to the same as development or production.
|
13 |
test: |
14 |
adapter: sqlite3 |
15 |
database: db/test.sqlite3 |
16 |
pool: 5 |
17 |
timeout: 5000 |
18 |
|
19 |
production: |
20 |
adapter: sqlite3 |
21 |
database: db/production.sqlite3 |
22 |
pool: 5 |
23 |
timeout: 5000 |
Beachten Sie, dass verschiedene Umgebungen zugewiesen sind. Rails hat drei Modi: Entwicklung, Test und Produktion. Jeder hat verschiedene Einstellungen und Datenbanken. Entwicklung ist die Standardumgebung. An dieser Stelle können wir unsere App starten, um sicherzustellen, dass sie funktioniert. Sie können sehen, es gibt ein Verzeichnis namens / script. Dieses Verzeichnis enthält Ruby-Skripte für die Interaktion mit unserer Anwendung. Einige wichtige sind / script / console und / script / server. Wir verwenden den Befehl / script / server, um einen einfachen Server für unsere Anwendung zu starten.
1 |
|
2 |
bookshelf $ ./script/server |
3 |
# then you should see something like this. Rails will start a different server depending on your platform, but it should look something like this:
|
4 |
=> Booting Mongrel |
5 |
=> Rails 2.3.5 application starting on http://0.0.0.0:3000 |
6 |
=> Call with -d to detach |
7 |
=> Ctrl-C to shutdown server |
Zeit, um die Anwendung zu besuchen. Zeigen Sie mit Ihrem Browser auf "http: // localhost: 3000" und Sie sollten diese Begrüßungsseite sehen:



Begrüßungsbildschirm Du fährst auf Schienen. Nun da der Code auf einer grundlegenden Ebene arbeitet, ist es Zeit, die Splash-Seite zu löschen und mit etwas Code zu beginnen.
1 |
|
2 |
bookshelf $ rm /public/index.html |
Fünfundzwanzig
Unsere Anwendung benötigt Daten. Erinnern Sie sich, was das bedeutet? Es bedeutet Modelle. Toll, aber wie generieren wir ein Modell? Schienen kommt mit einigen Generatoren zu allgemeinen Aufgaben. Der Generator ist die Datei / script / generate. Der Generator erstellt unsere model.rb-Datei zusammen mit einer Migration, um die Tabelle zur Datenbank hinzuzufügen. Eine Migrationsdatei enthält Code zum Hinzufügen / Löschen von Tabellen oder zum Ändern / Hinzufügen / Entfernen von Spalten aus Tabellen. Migrationen werden nacheinander ausgeführt, um die Tabellen zu erstellen. Führen Sie Migrationen (und verschiedene andere Befehle) mit "Rake" aus. Rake ist ein Ruby-Code-Runner. Bevor wir weiter kommen, sollten wir zunächst einige grundlegende Informationen für die Bücher definieren. Ein Buch hat diese Attribute:
- Titel: Zeichenfolge
- Gedanken: Text
Das ist genug, um die Anwendung zu starten. Beginnen Sie mit dem Generieren eines Modells mit diesen Feldern mithilfe des Modellgenerators:
1 |
|
2 |
bookshelf $ ./script/generate model Book title:string thoughts:text |
3 |
# notice how the attributes/types are passed to the generator. This will automatically create a migration for these attributes
|
4 |
# These are optional. If you leave them out, the generator will create an empty migration.
|
5 |
exists app/models/ |
6 |
exists test/unit/ |
7 |
exists test/fixtures/ |
8 |
create app/models/book.rb |
9 |
create test/unit/book_test.rb |
10 |
create test/fixtures/books.yml |
11 |
create db/migrate |
12 |
create db/migrate/20091202052507_create_books.rb |
13 |
# The generator created all the files we need to get our model up and running. We need to pay the most attention to these files:
|
14 |
# app/models/book.rb # where our code resides
|
15 |
# db/migrate/20091202052507_create_books.rb # code to create our books table.
|
Öffnen Sie die Migrationsdatei:
1 |
|
2 |
class CreateBooks < ActiveRecord::Migration |
3 |
def self.up |
4 |
create_table :books do |t| |
5 |
t.string :title |
6 |
t.text :thoughts |
7 |
|
8 |
t.timestamps |
9 |
end
|
10 |
end
|
11 |
|
12 |
def self.down |
13 |
drop_table :books |
14 |
end
|
15 |
end
|
Beachten Sie den create_table: books-Block. Hier werden Spalten erstellt. Ein ID-Primärschlüssel wird automatisch erstellt. t.timestamps fügt Spalten für created_at und updated_at hinzu. Führen Sie nun die Migration mit der Rake-Task db: migrate aus. db: migrate gilt für ausstehende Migrationen:
1 |
|
2 |
bookshelf $ rake db:migrate |
3 |
== CreateBooks: migrating ==================================================== |
4 |
-- create_table(:books) |
5 |
-> 0.0037s |
6 |
== CreateBooks: migrated (0.0038s) =========================================== |
Cool, jetzt haben wir einen Tisch, lass uns ein Dummy-Buch nur für Tritte in der Konsole erstellen. Die Rails-Konsole verwendet IRB (interactive ruby) und lädt alle Klassen für Ihr Projekt. IE Sie können auf alle Ihre Modelle zugreifen. Öffne die Konsole wie folgt:
1 |
|
2 |
bookshelf $ ./script/console |
3 |
>> # let's create a new model. You can specify a hash of assignments in the constructor to assign values like this: |
4 |
>> book = Book.new :title => 'Rails is awesome!' , :thoughts => 'Some sentence from a super long paragraph' |
5 |
=> #<Book id: nil, title: "Rails is awesome!", thoughts: "Some sentence from a super long paragraph", created_at: nil, updated_at: nil> # and ruby will display it back |
6 |
>> book.save |
7 |
=> true # now are book is saved in the database. We can query it like this: |
8 |
>> Book.all # find all books and return them in an array |
9 |
=> [#<Book id: 1, title: "Rails is awesome!", thoughts: "Some sentence from a super long paragraph", created_at: "2009-12-02 06:05:38", updated_at: "2009-12-02 06:05:38">] |
10 |
>> exit # now that our model is saved, let's exit the console. |
Jetzt, da wir Bücher erstellen können, brauchen wir eine Möglichkeit, sie dem Benutzer zu zeigen
Dreißig
Erinnere Controller? Wir benötigen einen Controller, um alle Bücher im System anzuzeigen. Dieses Szenario entspricht der Indexaktion in unserem BooksController (books_controller.rb), die wir noch nicht haben. Wie beim Generieren von Modellen verwenden Sie einen Generator, um den Controller zu erstellen:
1 |
|
2 |
bookshelf $ ./script/generate controller Books |
3 |
exists app/controllers/ |
4 |
exists app/helpers/ |
5 |
create app/views/books |
6 |
exists test/functional/ |
7 |
create test/unit/helpers/ |
8 |
create app/controllers/books_controller.rb |
9 |
create test/functional/books_controller_test.rb |
10 |
create app/helpers/books_helper.rb |
11 |
create test/unit/helpers/books_helper_test.rb |
12 |
# notice Rails created the file app/controllers/books_controller.rb? This is where we are going to define our actions or methods for the BooksController class
|
Wir müssen eine Aktion definieren, die alle Bücher findet und anzeigt. Wie haben wir alle Bücher gefunden? Früher haben wir Book.all benutzt. Unsere Strategie ist, Book.all zu verwenden und einer Instanzvariablen zuzuweisen. Warum eine Instanzvariable? Wir weisen Instanzvariablen zu, da Ansichten mit der Bindung der Controller gerendert werden. Du denkst wahrscheinlich Bindings und Instanzvariablen ... was ist los? Ansichten haben Zugriff auf in Aktionen definierte Variablen, jedoch nur auf Instanzvariablen. Warum, weil Instanzvariablen auf das Objekt und nicht auf die Aktion beschränkt sind. Lass uns etwas Code sehen:
1 |
|
2 |
class BooksController < ApplicationController |
3 |
# notice we've defined a method called index for a BooksController instance. We tie this together with routes
|
4 |
def index |
5 |
@books = Book.all # instance variables are prefixed with an @. If we said books = Book.all, we wouldn't be able to access books in the template |
6 |
end
|
7 |
end
|
Jetzt kann der Controller alle Bücher finden. Aber wie binden wir das an eine URL? Wir müssen einige Routen erstellen. Rails enthält einige nützliche Funktionen zum Generieren von RESTful-Routen (ein weiteres Prinzip von Rails). Dies erzeugt URLs wie / make und / make / 1 kombiniert mit HTTP-Verben, um zu bestimmen, welche Methode in unserem Controller aufgerufen werden soll. Verwenden Sie map.resources, um REST-konforme Routen zu erstellen. Öffne /config/routes.rb und ändere es wie folgt:
1 |
|
2 |
ActionController::Routing::Routes.draw do |map| |
3 |
map.resources :books |
4 |
end
|
Routes.rb kann für neue Benutzer geheimnisvoll aussehen. Glücklicherweise gibt es eine Möglichkeit, dieses Chaos zu entschlüsseln. Es gibt Routen Rake-Aufgabe, um alle Ihre Routing-Informationen anzuzeigen. Führen Sie das jetzt aus und werfen Sie einen Blick hinein:
1 |
|
2 |
bookshelf $ rake routes |
3 |
books GET /books(.:format) {:controller=>"books", :action=>"index"} |
4 |
POST /books(.:format) {:controller=>"books", :action=>"create"} |
5 |
new_book GET /books/new(.:format) {:controller=>"books", :action=>"new"} |
6 |
edit_book GET /books/:id/edit(.:format) {:controller=>"books", :action=>"edit"} |
7 |
book GET /books/:id(.:format) {:controller=>"books", :action=>"show"} |
8 |
PUT /books/:id(.:format) {:controller=>"books", :action=>"update"} |
9 |
DELETE /books/:id(.:format) {:controller=>"books", :action=>"destroy"} |
10 |
# as you can see this command can display a lot of information. On the left column we have a helper to generate a url, then the HTTP verb associated with the url, then the url, and finally the controller and action to call.
|
11 |
# for example GET /books will call BooksController#index or
|
12 |
# GET /books/1 will call BooksController#show
|
13 |
# the url helpers are very important but we'll get to them later. For now know that we are going to create a /books page to list all books
|
Jetzt müssen wir eine Vorlage erstellen, um alle unsere Bücher anzuzeigen. Erstellen Sie eine neue Datei mit dem Namen /app/views/books/index.html.erb, und fügen Sie Folgendes ein:
1 |
|
2 |
<% for book in @books do %> |
3 |
<h2><%=h book.title %></h2> |
4 |
<p><%= book.thoughts %></p> |
5 |
<% end %> |
Diese einfache Ansicht zeigt alle @books an und zeigt HTML für jedes Buch an. Beachten Sie einen feinen Unterschied. <% = wird verwendet, wenn Text ausgegeben werden soll. <% wird verwendet, wenn wir nicht sind. Wenn Sie dieser Regel nicht folgen, erhalten Sie eine Ausnahme. Beachten Sie auch die h vor book.title. h ist eine Methode, die HTML-Entitäten entkoppelt. Wenn Sie mit Ruby nicht vertraut sind, können Sie bei Methodenaufrufen off () weglassen, wenn sie nicht benötigt werden. h Text übersetzt sich in: h (Text).
Zeit, den Server zu starten und zu sehen, was wir haben. Starten Sie den Server und gehen Sie zu http: // localhost / books.
1 |
|
2 |
bookshelf $ ./script/server |
Wenn alles nach Plan läuft, sollten Sie etwas einfaches HTML sehen.



Fünfunddreißig
Wir haben ein Buch in unserem System, aber wir brauchen noch ein paar Bücher zum Spielen. Es gibt ein paar Möglichkeiten, dies zu tun. Ich mag den Fälschungsstein. Fälschung kann zufällige Zeichenfolgen wie Namen oder Lorem-Ipsum-Zeug erzeugen. Wir werden in unserer App eine Edelsteinabhängigkeit festlegen, das Juwel installieren und dann eine Rake-Aufgabe erstellen, um unsere Daten zu füllen. Schritt 1: Öffnen Sie /config/environment.rb und fügen Sie diese Zeile hinzu:
1 |
|
2 |
config.gem 'forgery' |
1 |
|
2 |
# now let's tell Rails to install all gems dependencies for this project
|
3 |
# gem install gemcutter # if you haven't already
|
4 |
# gem tumble # again, if you haven't already
|
5 |
bookshelf $ sudo rake gems:install |
Jetzt werden wir die Forgery-Klassen verwenden, um einige gefälschte Daten zu erstellen. Die Fälschung Dokumentation ist hier. Wir werden das LoremIsfumForgery verwenden, um einige grundlegende Daten zu erstellen. Wir können unsere eigenen Rake-Aufgaben definieren, indem wir eine .rake-Datei in / lib / tasks erstellen. Also erstelle eine neue Datei /lib/tasks/populate.rake:
1 |
|
2 |
begin
|
3 |
namespace :db do |
4 |
desc "Populate the development database with some fake data" |
5 |
task :populate => :environment do |
6 |
5.times do |
7 |
Book.create! :title => Forgery::LoremIpsum.sentence, :thoughts => Forgery::LoremIpsum.paragraphs(3) |
8 |
end
|
9 |
end
|
10 |
end
|
11 |
rescue LoadError |
12 |
puts "Please run: sudo gem install forgery" |
13 |
end
|
Diese Rake-Aufgabe erstellt fünf gefälschte Bücher. Beachten Sie, dass ich eine Begin / Rescue hinzugefügt habe. Wenn Sie eine Rake-Task ausführen, werden alle möglichen Aufgaben in der Rake-Initialisierung betrachtet. Wenn du vor dem Installieren des Edelsteins eine Rake-Aufgabe ausführen würdest, würde Rake in die Luft gehen. Wrapping es in einem Start / Rescue Stop Rake vor dem Abbruch. Führen Sie die Aufgabe aus, um unsere Datenbank zu füllen:
1 |
|
2 |
bookshelf $ rake db:populate |
3 |
bookshelf $ ./script/console # let's enter the console to verify it all worked |
4 |
>> Book.all |
5 |
=> [#<Book id: 1, title: "Rails is awesome!", thoughts: "Some sentence from a super long paragraph", created_at: "2009-12-02 06:05:38", updated_at: "2009-12-02 06:05:38">, #<Book id: 2, title: "Lorem ipsum dolor sit amet, consectetuer adipiscing...", thoughts: "Lorem ipsum dolor sit amet, consectetuer adipiscing...", created_at: "2009-12-02 07:28:05", updated_at: "2009-12-02 07:28:05">, #<Book id: 3, title: "Lorem ipsum dolor sit amet, consectetuer adipiscing...", thoughts: "Lorem ipsum dolor sit amet, consectetuer adipiscing...", created_at: "2009-12-02 07:28:05", updated_at: "2009-12-02 07:28:05">, #<Book id: 4, title: "Lorem ipsum dolor sit amet, consectetuer adipiscing...", thoughts: "Lorem ipsum dolor sit amet, consectetuer adipiscing...", created_at: "2009-12-02 07:28:05", updated_at: "2009-12-02 07:28:05">, #<Book id: 5, title: "Lorem ipsum dolor sit amet, consectetuer adipiscing...", thoughts: "Lorem ipsum dolor sit amet, consectetuer adipiscing...", created_at: "2009-12-02 07:28:05", updated_at: "2009-12-02 07:28:05">, #<Book id: 6, title: "Lorem ipsum dolor sit amet, consectetuer adipiscing...", thoughts: "Lorem ipsum dolor sit amet, consectetuer adipiscing...", created_at: "2009-12-02 07:28:05", updated_at: "2009-12-02 07:28:05">] |
6 |
>> exit |
Starten Sie den Server erneut und kehren Sie zu den / books-Seiten zurück. Das solltest du sehen:



Buch-Index Jetzt haben wir eine Liste von mehr als einem Buch. Was, wenn wir viele Bücher haben? Wir müssen die Ergebnisse paginieren. Es gibt ein anderes Juwel dafür. Das Juwel ist "will_paginate". Nach den gleichen Schritten wie zuvor, fügen wir eine Edelsteinabhängigkeit für 'will_paginate' und rake gems hinzu: install:
1 |
|
2 |
# in environment.rb
|
3 |
config.gem 'will_paginate' |
4 |
# from terminal
|
5 |
bookshelf $ sudo rake gems:install |
6 |
# then let's add more books to our db
|
7 |
bookshelf $ rake db:populate # run this a few times to get a large sample, or change the number in rake file |
Geh zurück zu deiner / Bücher Seite und du solltest an dieser Stelle von Büchern bombardiert werden. Es ist Zeit, die Seitennummerierung hinzuzufügen. Paginierung funktioniert auf zwei Ebenen. Der Controller entscheidet, welche Bücher in @books sein sollen, und die Ansicht sollte die Paginierungslinks anzeigen. Der Helfer will_paginate macht das sehr einfach. Wir verwenden die .paginate-Methode und den View-Helfer will_paginate, um Seitenlinks zu rendern. Alles was es braucht sind zwei Zeilen Code.
1 |
|
2 |
# books_controller.rb, change the previous line to:
|
3 |
@books = Books.paginate :page => params[:page], :per_page => 10 |
4 |
|
5 |
# index.html.erb, add this line after the loop:
|
6 |
<%= will_paginate @books %> |
Gehen Sie zurück zu Ihrer / make-Seite, und Sie sollten einige Paginierungslinks sehen (vorausgesetzt, Sie haben mehr als 10 Bücher)



Süss! Wir bewegen uns durch diese App. Es ist Zeit, unsere Seite ein wenig aufzupeppen. Ein Schlüssel-Rails-Prinzip ist DRY (Do not Repeat Yourself). Wir könnten die Übung machen, ein paar grundlegende CSS zu machen, um eine Seite in Ordnung zu bringen, oder wir könnten die Dinge DRY behalten und etwas Code verwenden, um es für uns zu tun. Wir werden Ryan Bates raffinierte Generatoren verwenden, um ein Layout für die Seite zu erstellen. Ein Layout ist eine Vorlage, die Ihre Ansichten ausfüllen können. Zum Beispiel können wir ein Layout verwenden, um die gesamte Struktur einer Seite zu bestimmen, und dann definieren, wo die Ansichten es ausfüllen. Da dies keine Projektabhängigkeit ist, tun wir das nicht muss es zu environment.rb hinzufügen. Wir können es einfach regelmäßig installieren.
1 |
|
2 |
# console
|
3 |
$ sudo gem install nifty-generators |
Führen Sie den Generator aus, um eine Layoutdatei und Stylesheets zu erstellen.
1 |
|
2 |
$ ./script/generate nifty_layout |
3 |
exists app/views/layouts |
4 |
exists public/stylesheets |
5 |
exists app/helpers |
6 |
create app/views/layouts/application.html.erb # this is our layout file |
7 |
create public/stylesheets/application.css # css file that styles the layout |
8 |
create app/helpers/layout_helper.rb # view helpers needed in the generator |
Sehen Sie sich die Datei application.html.erb an und sehen Sie, was sich darin befindet:
1 |
|
2 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" |
3 |
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
4 |
<html> |
5 |
<head> |
6 |
<title><%= h(yield(:title) || "Untitled") %></title> |
7 |
<%= stylesheet_link_tag 'application' %> |
8 |
<%= yield(:head) %> |
9 |
</head> |
10 |
<body> |
11 |
<div id="container"> |
12 |
<%- flash.each do |name, msg| -%> |
13 |
<%= content_tag :div, msg, :id => "flash_#{name}" %> |
14 |
<%- end -%> |
15 |
|
16 |
<%- if show_title? -%> |
17 |
<h1><%=h yield(:title) %></h1> |
18 |
<%- end -%> |
19 |
|
20 |
<%= yield %> |
21 |
</div> |
22 |
</body> |
23 |
</html> |
Siehst du diese Erträge? Dort füllt eine Ansicht das Layout aus. Der letzte Ertrag hat kein Argument. Standardinhalte gehen dorthin. Bei Yields mit einem Argument muss der Inhalt mithilfe von content_for definiert werden. Repariere die index.html.erb-Ansicht, um mit dem neuen Layout zu gehen:
1 |
|
2 |
<% title 'My Books' %> |
3 |
|
4 |
<% for book in @books do %> |
5 |
<h2><%=h book.title %></h2> |
6 |
<p><%= book.thoughts %></p> |
7 |
<% end %> |
8 |
|
9 |
<%= will_paginate @books %> |
Wir haben nur die Titelmethode hinzugefügt, die den Titel für eine Seite festlegt. Der Titelhelfer ruft content_for: title auf und setzt ihn auf das Argument. Unsere Ansicht füllt die letzte Ausbeute aus. Sieh dir die Ergebnisse an!



Vierzig
Jetzt, wo unsere Anwendung besser aussieht, fügen wir etwas Interaktion hinzu. Im typischen Web 2.0-Stil erlauben wir Nutzern, Kommentare zu unseren Inhalten abzugeben, aber wir werden den Nutzer nicht zur Registrierung auffordern. Wir müssen ein neues Modell mit dem Namen Kommentar erstellen. Ein Kommentar enthält Text, einen Autor und ein assoziiertes Buch. Wie verbinden wir diese beiden Modelle miteinander? Verbände. Rails bietet diese Zuordnungen an: gehört zu_to, has_many, has_one und has_and_belongs_to many. Es sollte leicht zu erkennen sein, dass ein Buch viele Kommentare enthält und ein Kommentar in ein Buch gehört. Wir verwenden also einen Generator, um das Kommentarmodell und die Migration zu erstellen:
1 |
|
2 |
$ ./script/generate model Comment text:text author:string |
3 |
exists app/models/ |
4 |
exists test/unit/ |
5 |
exists test/fixtures/ |
6 |
create app/models/comment.rb |
7 |
create test/unit/comment_test.rb |
8 |
create test/fixtures/comments.yml |
9 |
exists db/migrate |
10 |
create db/migrate/20091202081421_create_comments.rb |
Deutliche Leser werden feststellen, dass diese Migration die Fremdschlüsselspalte nicht enthält. Das müssen wir selbst hinzufügen. Öffnen Sie Ihre create_comments.rb-Migration:
1 |
|
2 |
class CreateComments < ActiveRecord::Migration |
3 |
def self.up |
4 |
create_table :comments do |t| |
5 |
t.text :text |
6 |
t.string :author |
7 |
t.belongs_to :book # creates a new integer column named book_id |
8 |
t.timestamps |
9 |
end
|
10 |
end
|
11 |
|
12 |
def self.down |
13 |
drop_table :comments |
14 |
end
|
15 |
end
|
1 |
|
2 |
# now migrate your database
|
3 |
$ rake db:migrate |
4 |
rake db:migrate |
5 |
(in /Users/adam/Code/bookshelf) |
6 |
== CreateComments: migrating ================================================= |
7 |
-- create_table(:comments) |
8 |
-> 0.0021s |
9 |
== CreateComments: migrated (0.0022s) ======================================== |
Jetzt ist es an der Zeit, unsere Modelle mit den Rails-Assoziationen zu verknüpfen. Wir rufen die Methode im Klassenkörper des Modells auf. Rails verwendet Metaprogrammierung, um die Methoden zu generieren, die benötigt werden, damit unsere Assoziation funktioniert. Wir bearbeiten unsere Dateien comment.rb und book.rb:
1 |
|
2 |
# book.rb
|
3 |
class Book < ActiveRecord::Base |
4 |
has_many :comments |
5 |
end
|
6 |
|
7 |
# comment.rb
|
8 |
class Comment < ActiveRecord::Base |
9 |
belongs_to :book |
10 |
end
|
Book-Instanzen haben nun eine Methode, mit der man alle Kommentare kommentieren kann. Kommentarinstanzen verfügen über eine Methode namens .book, die das zugehörige Buch zurückgibt. Verwenden Sie den Operator <<, um Objekte zu Arrays hinzuzufügen. Mal sehen, wie es in der Konsole funktioniert:
1 |
|
2 |
$ ./script/console |
3 |
>> book = Book.find(1) |
4 |
=> #<Book id: 1, title: "Rails is awesome!", thoughts: "Some sentence from a super long paragraph", created_at: "2009-12-02 06:05:38", updated_at: "2009-12-02 06:05:38"> |
5 |
>> comment = Comment.new :text => "This is an comment", :author => "Adam" |
6 |
=> #<Comment id: nil, text: "This is an comment", author: "Adam", book_id: nil, created_at: nil, updated_at: nil> |
7 |
>> book.comments << comment |
8 |
=> [#<Comment id: 1, text: "This is an comment", author: "Adam", book_id: 1, created_at: "2009-12-02 08:25:47", updated_at: "2009-12-02 08:25:47">] |
9 |
>> book.save |
10 |
=> true |
11 |
>> book.comments |
12 |
=> [#<Comment id: 1, text: "This is an comment", author: "Adam", book_id: 1, created_at: "2009-12-02 08:25:47", updated_at: "2009-12-02 08:25:47">] |
13 |
>> comment.book |
14 |
=> #<Book id: 1, title: "Rails is awesome!", thoughts: "Some sentence from a super long paragraph", created_at: "2009-12-02 06:05:38", updated_at: "2009-12-02 06:05:38"> |
15 |
>> exit |
In der Konsolensitzung habe ich eines der vorhandenen Bücher gefunden und dann einen neuen Kommentar erstellt. Als nächstes habe ich es den book.comments hinzugefügt. Dann speichere ich das Buch. Das Buch muss gespeichert werden, damit die Assoziation gespeichert werden kann. Was kommt als nächstes? Wir müssen eine Seite erstellen, auf der der Benutzer ein Buch und alle Kommentare sehen kann. Diese Seite sollte auch ein Formular enthalten, in dem der Benutzer seinen Kommentar hinzufügen kann. Erstellen Sie eine neue Aktion im Buch-Controller, um die Details für ein bestimmtes Buch anzuzeigen. Das Buch wird von ID gefunden. Öffnen Sie books_controller.rb und fügen Sie Folgendes hinzu:
1 |
|
2 |
def show |
3 |
@book = Book.find params[:id] |
4 |
end
|
Erstellen Sie eine neue Vorlage für diese Aktion unter /app/views/books/show.html.erb und fügen Sie Folgendes ein:
1 |
|
2 |
<% title @book.title %> |
3 |
|
4 |
<h2><%=link_to(h(@book.title), book_path(@book)) %></h2> |
5 |
<p><%= @book.thoughts %></p> |
Fügen wir nun einige Links für die Indexaktionen hinzu, um die show-Aktion zu verknüpfen:
1 |
|
2 |
# update index.html.erb contents to:
|
3 |
<% title 'My Books' %> |
4 |
|
5 |
<% for book in @books do %> |
6 |
<h2><%=link_to(h(book.title), book_path(book)) %></h2> |
7 |
<p><%= book.thoughts %></p> |
8 |
<% end %> |
9 |
|
10 |
<%= will_paginate @books %> |
Erinnerst du dich an unsere URL-Helfer von Rake-Routen? Wir verwenden book_path, um eine URL für die Show-Aktionen des Buch-Controllers zu generieren. Wenn Sie sich nicht erinnern, überprüfen Sie die Rake-Routen erneut. link_to ist ein Helfer, um ein Link-Tag zu generieren. Jetzt starten wir unseren Server und klicken durch die App. Jetzt sollten Sie einige hässliche blaue Links haben. Klicken Sie auf Ihren Buchtitel und dieser sollte nach / books / gehen: id aka BooksController # show:



Links! Zeit, einige Kommentare anzuzeigen. Erinnern Sie sich daran, dass wir bei der Konsolensitzung ein bisschen zurück waren? Eines unserer Bücher enthält einige Kommentare. Lassen Sie uns unseren Controller aktualisieren, um die Kommentare zu finden, und unsere show.html.erb, um sie anzuzeigen.
1 |
|
2 |
# books_controller.rb
|
3 |
def show |
4 |
@book = Book.find(params[:id]) |
5 |
@comments = @book.comments |
6 |
end
|
7 |
|
8 |
# show.html.erb
|
9 |
<% title @book.title %> |
10 |
|
11 |
<h2><%=link_to(h(@book.title), book_path(@book)) %></h2> |
12 |
<p><%= @book.thoughts %></p> |
13 |
|
14 |
<% if @comments %> |
15 |
<h3>Comments</h3> |
16 |
|
17 |
<% for comment in @comments do %> |
18 |
<p><strong><%=h(comment.author) %></strong>: <%=h comment.text %> |
19 |
<% end %> |
20 |
<% end %> |
Also weisen wir @ comments im Controller zu, um alle Kommentare des Buches zu sein, und führen dann eine Schleife in der Ansicht aus, um sie anzuzeigen. Gehen Sie zu / books / 1 (1 kam von Book.find (1) in der Konsolensitzung). Sieh dir das an:



Bemerkungen Jetzt benötigen wir das Formular, um einen neuen Kommentar zu erstellen. Wir brauchen zwei Dinge. 1, A Kommentare Controller zum Speichern des Kommentars und 2 eine Route zu dieser Aktion. Lass uns zuerst # 1 angehen.
1 |
|
2 |
bookshelf $ ./script/generate controller Comments |
Erstellen Sie eine Aktion, die einen neuen Kommentar instanziiert, ihre Attribute (text / author) aus den übermittelten Formulardaten einstellt und speichert.
1 |
|
2 |
class CommentsController < ApplicationController |
3 |
def create |
4 |
book = Book.find params[:book_id] |
5 |
comment = book.comments.new params[:comment] |
6 |
comment.save |
7 |
flash[:notice] = 'Comment saved' |
8 |
redirect_to book_path(book) |
9 |
end
|
10 |
end
|
Zuerst findet der Code das Buch, erstellt dann einen neuen Kommentar aus den Formulardaten, speichert ihn, legt eine Nachricht fest und leitet dann zurück zur Seite des Buches. params enthält einen Hash aller GET / POST-Daten mit einer Anfrage. Jetzt müssen wir eine Route zu der Aktion des Controllers erstellen. Öffnen Sie routes.rb:
1 |
|
2 |
ActionController::Routing::Routes.draw do |map| |
3 |
map.resources :books do |book| |
4 |
book.resources :comments, :only => :create |
5 |
end
|
6 |
end
|
1 |
|
2 |
bookshelf $ rake routes |
3 |
# We needed to add a route to create a new comment for a book. We need to know what book we are creating a comment for, so we need a book_id in the route. Look at the book_comment line.
|
4 |
# book_comment is tied to our CommentsController#create
|
5 |
book_comments POST /books/:book_id/comments(.:format) {:controller=>"comments", :action=>"create"} |
6 |
books GET /books(.:format) {:controller=>"books", :action=>"index"} |
7 |
POST /books(.:format) {:controller=>"books", :action=>"create"} |
8 |
new_book GET /books/new(.:format) {:controller=>"books", :action=>"new"} |
9 |
edit_book GET /books/:id/edit(.:format) {:controller=>"books", :action=>"edit"} |
10 |
book GET /books/:id(.:format) {:controller=>"books", :action=>"show"} |
11 |
PUT /books/:id(.:format) {:controller=>"books", :action=>"update"} |
12 |
DELETE /books/:id(.:format) {:controller=>"books", :action=>"destroy"} |
13 |
# every time you modify routes.rb you'll need to restart the server
|
14 |
# kill the server process you have running with ^c (ctrl + c) and start it again
|
Gehe zurück zur / books-Seite und achte darauf, dass nichts explodiert ist. Alles sollte gut und schön sein. Jetzt zum Erstellen des Formulars. Wir benötigen ein Formular, das POST-Daten an / book /: book_id / comments sendet. Zum Glück hat Rails dafür den perfekten Helfer: form_for. form_for nimmt einige Modelle und generiert eine Route für sie. Wir übergeben form_for einen Block, um Formulareingaben zu erstellen. Gehen Sie weiter und fügen Sie das unten in Ihrer show.html.erb ein:
1 |
|
2 |
<h3>Post Your Comment</h3> |
3 |
<% form_for([@book, Comment.new]) do |form| %> |
4 |
<p><%= form.label :author %></p> |
5 |
<p><%= form.text_field :author %></p> |
6 |
|
7 |
<p><%= form.label :text, 'Comment' %></p> |
8 |
<p><%= form.text_area :text %></p> |
9 |
|
10 |
<%= form.submit 'Save' %> |
11 |
<% end %> |
Wir rufen form_for auf, um ein neues Formular für den Buchkommentar zu erstellen, und verwenden dann den text_field / text_area, um Eingaben für Attribute zu erstellen. An dieser Stelle können wir weitermachen und einen Kommentar abgeben. Füllen Sie das Formular und Viola Sie haben jetzt Kommentare!



Wir können kommentieren! Siehst du das grüne Ding? Das ist der Blitz. Der Flash ist eine Möglichkeit, Nachrichten zwischen Aktionen zu speichern. Es ist perfekt, um kleine Nachrichten wie diese zu speichern. Aber was machen wir, wenn ein Buch zu viele Kommentare enthält? Wir paginieren sie wie zuvor. Lassen Sie uns einige Änderungen am Controller vornehmen und sehen Sie sich Folgendes an:
1 |
|
2 |
# books_controller.rb
|
3 |
def show |
4 |
@book = Book.find(params[:id]) |
5 |
@comments = @book.comments.paginate :page => params[:page], :per_page => 10, :order => 'created_at ASC' |
6 |
end
|
1 |
|
2 |
# show.html.erb
|
3 |
|
4 |
<% title @book.title %> |
5 |
|
6 |
<h2><%=link_to(h(@book.title), book_path(@book)) %></h2> |
7 |
<p><%= @book.thoughts %></p> |
8 |
|
9 |
<% if @comments %> |
10 |
<h3>Comments</h3> |
11 |
|
12 |
<% for comment in @comments do %> |
13 |
<p><strong><%=h(comment.author) %></strong>: <%=h comment.text %> |
14 |
<% end %> |
15 |
|
16 |
<%= will_paginate @comments %> |
17 |
<% end %> |
18 |
|
19 |
<h3>Post Your Comment</h3> |
20 |
<% form_for([@book, Comment.new]) do |form| %> |
21 |
<p><%= form.label :author %></p> |
22 |
<p><%= form.text_field :author %></p> |
23 |
|
24 |
<p><%= form.label :text, 'Comment' %></p> |
25 |
<p><%= form.text_area :text %></p> |
26 |
|
27 |
<%= form.submit 'Save' %> |
28 |
<% end %> |
Fangen Sie an, Ihre Bücher zu kommentieren, und Sie sollten eine Paginierung sehen.



Jetzt können die Leute kommentieren und alles wird paginiert, aber wir verpassen etwas. Wir haben kein Web-Interface zum Erstellen von Büchern. Wir müssen dafür ein Formular erstellen. Auch wir sind die Admin, also nur ich sollte Bücher erstellen dürfen. Das bedeutet, dass wir einen Benutzer erstellen, sich anmelden und prüfen müssen, ob er eine Aktion ausführen kann.
Fünfzig
Jetzt werden wir die CRUD-Funktionalität für Administratoren implementieren. Zuerst werden wir Aktionen zum Erstellen, Bearbeiten und Löschen von Büchern implementieren. Dann erstellen wir eine Admin-Anmeldung. Schließlich stellen wir sicher, dass nur Administratoren diese Aktionen ausführen können.
Das Erstellen neuer Bücher erfordert zwei neue Aktionen. Eine Aktion, die ein Formular für ein neues Buch rendert. Diese Aktion wird als "neu" bezeichnet. Die zweite heißt "create". Diese Aktion übernimmt die Formularparameter und speichert sie in der Datenbank. Öffne deine books_controller.rb und füge folgende Aktionen hinzu:
1 |
|
2 |
def new |
3 |
@book = Book.new |
4 |
end
|
5 |
|
6 |
def create |
7 |
@book = Book.new params[:book] |
8 |
if @book.save |
9 |
flash[:notice] = "#{@book.title} saved." |
10 |
redirect_to @book |
11 |
else
|
12 |
render :new |
13 |
end
|
14 |
end
|
Wir brauchen auch eine neue Ansicht, die ein Formular anzeigt. Erstelle eine neue Datei /apps/views/books/new.html.erb und füge sie ein:
1 |
|
2 |
<% form_for(@book) do |form| %> |
3 |
<p> |
4 |
<%= form.label :title %><br/> |
5 |
<%= form.text_field :title %> |
6 |
</p> |
7 |
|
8 |
<p> |
9 |
<%= form.label :thoughts %><br/> |
10 |
<%= form.text_area :thoughts %> |
11 |
</p> |
12 |
|
13 |
<%= form.submit %> |
14 |
<% end %> |
Jetzt können wir ein neues Buch erstellen. Richten Sie Ihren Browser auf / books / new und Sie sollten dieses Formular sehen. Kopf gehen und ein neues Buch erstellen. Nachdem Sie Ihr Formular ausgefüllt haben, sollten Sie Ihr neues Buch sehen.




Löschen Sie den doppelten Header in /app/views/books/show.html.erb und fügen Sie einige Links zu Aktionen hinzu, die ein Administrator für dieses Buch ausführen kann. Öffne diese Datei und setze ihren Inhalt auf:
1 |
|
2 |
<% title @book.title %> |
3 |
|
4 |
<p><%= @book.thoughts %></p> |
5 |
|
6 |
<% if @comments %> |
7 |
<h3>Comments</h3> |
8 |
|
9 |
<% for comment in @comments do %> |
10 |
<p><strong><%=h(comment.author) %></strong>: <%=h comment.text %> |
11 |
<% end %> |
12 |
|
13 |
<%= will_paginate @comments %> |
14 |
<% end %> |
15 |
|
16 |
<h3>Post Your Comment</h3> |
17 |
<% form_for([@book, Comment.new]) do |form| %> |
18 |
<p><%= form.label :author %></p> |
19 |
<p><%= form.text_field :author %></p> |
20 |
|
21 |
<p><%= form.label :text, 'Comment' %></p> |
22 |
<p><%= form.text_area :text %></p> |
23 |
|
24 |
<%= form.submit 'Save' %> |
25 |
<% end %> |
26 |
|
27 |
<p> |
28 |
Admin Actions: |
29 |
<%= link_to 'Edit', edit_book_path(@book) %> | |
30 |
<%= link_to 'Delete', book_path(@book), :method => :delete, :confirm => "Are you sure?" %> |
31 |
</p> |
Gehen Sie zu einer Buchseite und Sie sollten sehen:



Jetzt, da wir einige Links zum Bearbeiten und Löschen haben, können Sie sie implementieren. Das Bearbeiten eines Buches funktioniert genauso wie das Erstellen eines neuen. Wir benötigen eine Aktion, die ein Bearbeitungsformular anzeigt, und eine, um die Änderungen zu speichern. Löschen ist nur eine Aktion, die den Datensatz aus der Datenbank löscht. Öffnen Sie books_controller.rb und fügen Sie diese Aktionen hinzu:
1 |
|
2 |
def edit |
3 |
@book = Book.find params[:id] |
4 |
end
|
5 |
|
6 |
def update |
7 |
@book = Book.find params[:id] |
8 |
if @book.update_attributes(params[:book]) |
9 |
flash[:notice] = "#{@book.title} saved." |
10 |
redirect_to @book |
11 |
else
|
12 |
render :edit |
13 |
end
|
14 |
end
|
15 |
|
16 |
def destroy |
17 |
book = Book.find params[:id] |
18 |
book.destroy |
19 |
flash[:notice] = "#{book.title} deleted." |
20 |
redirect_to books_path |
21 |
end
|
Die Editieraktion findet das angeforderte Buch von der ID in der URL. Die Aktualisierungsaktion sucht das Buch anhand der ID und verwendet die Methode update_attributes, um die neuen Werte aus dem Formular festzulegen. Löschen findet das Buch nach ID und löscht es. Dann leitet es Sie zurück in die Bücherliste.
Als nächstes müssen wir ein Bearbeitungsformular erstellen. Dieses Formular entspricht genau dem Formular zum Erstellen. Wir können die Datei show.html.erb einfach zu edit.html.erb vervielfältigen. Alles, was wir tun werden, ist den Titel zu ändern. Erstelle eine neue Datei in /app/views/books/edit.html.erb und füge diese ein:
1 |
|
2 |
<% title "Editing #{@book.title}" %> |
3 |
|
4 |
<% form_for(@book) do |form| %> |
5 |
<p> |
6 |
<%= form.label :title %><br/> |
7 |
<%= form.text_field :title %> |
8 |
</p> |
9 |
|
10 |
<p> |
11 |
<%= form.label :thoughts %><br/> |
12 |
<%= form.text_area :thoughts %> |
13 |
</p> |
14 |
|
15 |
<%= form.submit %> |
16 |
<% end %> |
Klicken Sie nun auf einer der Seiten des Buches auf den Link zum Bearbeiten. Sie sollten eine vertraute Form sehen:



Beachten Sie, wie Rails die Eingaben mit den gespeicherten Werten gefüllt hat? Schön, huh. Gehen Sie voran und speichern Sie einige Änderungen an einem Buch. Wenn du fertig bist, solltest du Folgendes sehen:



Ein bearbeitetes Buch anzeigen. Löschen Sie das Buch jetzt. Sie sollten einen Bestätigungsdialog erhalten und dann zurück zu / books weitergeleitet werden.






Bist du sicher? Buch gelöscht. Fügen Sie einen Link hinzu, um auf der Indexseite ein neues Buch zu erstellen. Öffne /app/views/books/index.html.erb und füge folgendes hinzu:
1 |
|
2 |
<p> |
3 |
Admin actions: <%= link_to 'New Book', new_book_path %> |
4 |
</p> |
Jetzt haben wir CRUD-Funktionalität. Wir müssen unseren Admin-Benutzer erstellen.
Fünfundfünfzig
Das Verwalten von Benutzeranmeldungen ist ein gelöstes Problem in Rails. Sie müssen selten Ihr eigenes Authentifizierungssystem schreiben. Wir werden den authlogischen Edelstein benutzen. Authlogic bietet einfache Mechanismen zum Authentifizieren von Benutzern und Speichern von Sitzungen. Dies ist der perfekte App für unsere App. Wir benötigen einen Administrator, um sich anzumelden, damit er Bücher erstellen / bearbeiten / löschen kann. Zuerst beginnen wir mit der Installation des Authlogic Gems.
1 |
|
2 |
# add config.gem 'authlogic' in environment.rb
|
3 |
bookshelf $ sudo rake gems:install |
Erstelle ein neues Modell, um die Admins zu halten. Da unsere Nutzer nur Administratoren sind, nennen wir das Modell Admin. Das Modell benötigt nur ein Login-Attribut. Generieren Sie das Modell mit dem Script / Generate-Modell:
1 |
|
2 |
bookshelf $ ./script/generate model Admin login:string |
3 |
exists app/models/ |
4 |
exists test/unit/ |
5 |
exists test/fixtures/ |
6 |
create app/models/admin.rb |
7 |
create test/unit/admin_test.rb |
8 |
create test/fixtures/admins.yml |
9 |
exists db/migrate |
10 |
create db/migrate/20091204202129_create_admins.rb |
Fügen Sie nun unserem Admin-Modell authlogic-spezifische Spalten hinzu. Öffnen Sie die gerade erstellte Migration und fügen Sie diese ein:
1 |
|
2 |
class CreateAdmins < ActiveRecord::Migration |
3 |
def self.up |
4 |
create_table :admins do |t| |
5 |
t.string :login |
6 |
t.string :crypted_password, :null => false |
7 |
t.string :password_salt, :null => false |
8 |
t.string :persistence_token, :null => false |
9 |
t.timestamps |
10 |
end
|
11 |
end
|
12 |
|
13 |
def self.down |
14 |
drop_table :admins |
15 |
end
|
16 |
end
|
Jetzt migrieren Sie Ihre Datenbank.
1 |
|
2 |
bookshelf $ rake db:migrate |
3 |
== CreateAdmins: migrating =================================================== |
4 |
-- create_table(:admins) |
5 |
-> 0.0025s |
6 |
== CreateAdmins: migrated (0.0026s) ========================================== |
Jetzt wird das Administratormodell erstellt. Als nächstes müssen wir eine authlogische Sitzung für diesen Administrator erstellen. Authlogic enthält dafür einen Generator:
1 |
|
2 |
bookshelf $ ./script/generate session admin_session |
3 |
exists app/models/ |
4 |
create app/models/admin_session.rb |
Als nächstes müssen wir einige Routen für das An- und Abmelden erstellen. Öffnen Sie routes.rb und fügen Sie diese Zeile hinzu:
1 |
|
2 |
map.resource :admin_session |
Jetzt brauchen wir einen Controller, der das An- und Abmelden übernimmt. Generiere diesen Controller mit dem Generator:
1 |
|
2 |
bookshelf $ ./script/generate controller AdminSessions |
3 |
exists app/controllers/ |
4 |
exists app/helpers/ |
5 |
create app/views/admin_sessions |
6 |
exists test/functional/ |
7 |
exists test/unit/helpers/ |
8 |
create app/controllers/admin_sessions_controller.rb |
9 |
create test/functional/admin_sessions_controller_test.rb |
10 |
create app/helpers/admin_sessions_helper.rb |
11 |
create test/unit/helpers/admin_sessions_helper_test.rb |
Öffne nun /app/controllers/admin_sessions_controller.rb und füge das ein:
1 |
|
2 |
class AdminSessionsController < ApplicationController |
3 |
def new |
4 |
@admin_session = AdminSession.new |
5 |
end
|
6 |
|
7 |
def create |
8 |
@admin_session = AdminSession.new(params[:admin_session]) |
9 |
if @admin_session.save |
10 |
flash[:notice] = "Login successful!" |
11 |
redirect_to books_path |
12 |
else
|
13 |
render :action => :new |
14 |
end
|
15 |
end
|
16 |
|
17 |
def destroy |
18 |
current_admin_session.destroy |
19 |
flash[:notice] = "Logout successful!" |
20 |
redirect_to books_path |
21 |
end
|
22 |
end
|
Beeindruckend! Es scheint, als hätten wir gerade viel getan, aber wir haben es nicht getan. Wir haben gerade 2 neue Modelle erstellt. Ein Modell, um unsere Admins zu halten, und das andere, um Informationen zur Admin-Sitzung zu halten. Schließlich haben wir einen Controller für das An- und Abmelden geschaffen. Jetzt benötigen wir eine Ansicht, um ein Login-Formular anzuzeigen. Erstelle eine neue Datei unter /app/views/admin_sessions/new.html.erb und füge diese ein:
1 |
|
2 |
<% title 'Login' %> |
3 |
|
4 |
<% form_for @admin_session, :url => admin_session_path do |f| %> |
5 |
<%= f.error_messages %> |
6 |
<p> |
7 |
<%= f.label :login %><br /> |
8 |
<%= f.text_field :login %> |
9 |
</p> |
10 |
|
11 |
<p> |
12 |
<%= f.label :password %><br /> |
13 |
<%= f.password_field :password %> |
14 |
</p> |
15 |
|
16 |
<%= f.submit "Login" %> |
17 |
<% end %> |
Wir sind fast fertig. Wir müssen unserem Admin-Modell immer noch mitteilen, dass es authlogic verwendet und unserem Anwendungscontroller etwas Logik hinzufügt, um Sitzungsinformationen zu erhalten. Alle Controller erben von application_controller, also ist es ein guter Weg, Methoden zwischen Controllern zu teilen. Öffne /app/controllers/application_controller.rb und füge folgendes ein:
1 |
|
2 |
class ApplicationController < ActionController::Base |
3 |
helper :all # include all helpers, all the time |
4 |
protect_from_forgery # See ActionController::RequestForgeryProtection for details |
5 |
|
6 |
# Scrub sensitive parameters from your log
|
7 |
# filter_parameter_logging :password
|
8 |
|
9 |
filter_parameter_logging :password, :password_confirmation |
10 |
helper_method :current_admin_session, :current_admin |
11 |
|
12 |
private
|
13 |
def current_admin_session |
14 |
return @current_admin_session if defined?(@current_admin_session) |
15 |
@current_admin_session = AdminSession.find |
16 |
end
|
17 |
|
18 |
def current_admin |
19 |
return @current_admin if defined?(@current_admin) |
20 |
@current_admin = current_admin_session && current_admin_session.user |
21 |
end
|
22 |
end
|
Fügen Sie diese Zeile in /app/models/admin.rb innerhalb der Klasse hinzu:
1 |
|
2 |
# /app/models/admin.rb
|
3 |
acts_as_authentic
|
Endlich sind wir bereit, uns an- und abzumelden. All das, was wir gemacht haben, war fast rein von den authlogischen Dokumentationsbeispielen. Dies ist eine Standardkonfiguration für viele Anwendungen. Wenn Sie mehr darüber erfahren möchten, wie autologic funktioniert, können Sie hier nachlesen. Hier ist eine Zusammenfassung von dem, was wir getan haben.
- Installiere den authlogischen Edelstein
- Erstellen Sie ein Admin-Modell, um diegrundlegenden Informationen wie Login / Passwort zu speichern
- Fügen Sie der Admin-Tabelle authlogicspezifische Spalten hinzu
- Generierte eine authlogic admin session
- Routen zum An- und Abmelden erstellt
- Generierte einen AdminSession-Controller, um die gesamte Arbeit zu erledigen
- Erstellt eine Ansicht, die ein Anmeldeformular anzeigt
- Methoden zu ApplicationController für persistente Sitzungen hinzugefügt
- Habe dem Admin-Modell gesagt, dass es authlogic
Es ist Zeit, das Administratorkonto zu erstellen. Unsere Anwendung ist einfach und hat nur einen Administrator. Da wir nur einen Admin haben, können wir die Konsole einfach benutzen. Da wir diesen Benutzer später bei der Bereitstellung erneut erstellen müssen, macht es keinen Sinn, dasselbe zweimal zu tun. Rails verfügt nun über eine Funktionalität zum Seeding der Datenbank. Dies ist perfekt zum Erstellen der ersten Datensätze. Es gibt eine Datei /db/seeds.rb, in der Sie Ruby-Code schreiben können, um Ihre ersten Modelle zu erstellen. Dann können Sie diese Datei über Rake db: seed ausführen. Um unser Admin-Modell zu erstellen, benötigen wir einen Login, ein Passwort und eine Passwortbestätigung. Öffne /db/seeds.rb und füge das ein. Geben Sie den Benutzernamen mit dem gewünschten Namen ein.
1 |
|
2 |
Admin.create! :login => 'Adam', :password => 'nettuts', :password_confirmation => 'nettuts' |
Wir benutzen das create! Methode, weil es eine Ausnahme auslöst, wenn der Datensatz nicht gespeichert werden kann. Gehen Sie voran und führen Sie die Rake-Aufgabe aus, um die Datenbank zu erstellen:
1 |
|
2 |
bookshelf $ rake db:seed |
Jetzt sollten wir uns einloggen können. Starten Sie den Server neu, um die neuen Routen zu erhalten. Gehe zu / admin_session / neu. Das solltest du sehen:



Login Formular Mach weiter und fülle es aus und jetzt solltest du eingeloggt sein!

Jetzt, wo sich Admins anmelden können, können wir ihnen Zugriff auf die neue / edit / delete-Funktion gewähren. Rails hat diese tollen Dinge, die man Filter nennt. Filter sind Dinge, die Sie an Punkten im Anforderungslebenszyklus ausführen können. Der beliebteste Filter ist ein before_filter. Dieser Filter wird vor einer Aktion im Controller ausgeführt. Wir können einen Vorher-Filter im Buch-Controller erstellen, der überprüft, ob wir einen eingeloggten Administrator haben. Der Filter leitet Benutzer, die nicht eingeloggt sind, um und verhindert damit unberechtigten Zugriff. Öffne books_controller.rb und füge folgende Zeilenhinzu:
1 |
|
2 |
# first line inside the class:
|
3 |
before_filter :login_required, :except => [:index, :show] |
4 |
|
5 |
# after all the actions
|
6 |
private
|
7 |
def login_required |
8 |
unless current_admin |
9 |
flash[:error] = 'Only logged in admins an access this page.' |
10 |
redirect_to books_path |
11 |
end
|
12 |
end
|
Jetzt müssen wir unsere Ansichten aktualisieren, um die Admin-Links nur anzuzeigen, wenn ein Administrator angemeldet ist. Das ist einfach genug. Alles, was wir tun müssen, ist es in ein if zu wickeln.
1 |
|
2 |
# show.html.erb
|
3 |
<% if current_admin %> |
4 |
<p> |
5 |
Admin Actions: |
6 |
<%= link_to 'Edit', edit_book_path(@book) %> | |
7 |
<%= link_to 'Delete', book_path(@book), :method => :delete, :confirm => "Are you sure?" %> |
8 |
</p> |
9 |
<% end %> |
10 |
|
11 |
# index.html.erb
|
12 |
<% if current_admin %> |
13 |
<p> |
14 |
Admin actions: <%= link_to 'New Book', new_book_path %> |
15 |
</p> |
16 |
<% end %> |
Wir müssen noch einen Login / Logout-Link hinzufügen. Das sollte auf jeder Seite gehen. Eine einfache Möglichkeit, etwas auf jede Seite zu setzen, ist das Hinzufügen zum Layout.
1 |
|
2 |
# /app/views/layouts/application.erb
|
3 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" |
4 |
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
5 |
<html> |
6 |
<head> |
7 |
<title><%= h(yield(:title) || "Untitled") %></title> |
8 |
<%= stylesheet_link_tag 'application' %> |
9 |
<%= yield(:head) %> |
10 |
</head> |
11 |
<body> |
12 |
<div id="container"> |
13 |
<%- flash.each do |name, msg| -%> |
14 |
<%= content_tag :div, msg, :id => "flash_#{name}" %> |
15 |
<%- end -%> |
16 |
|
17 |
<%- if show_title? -%> |
18 |
<h1><%=h yield(:title) %></h1> |
19 |
<%- end -%> |
20 |
|
21 |
<%= yield %> |
22 |
|
23 |
<% if current_admin %> |
24 |
<p><%= link_to 'Logout', admin_session_path(current_admin_session), :method => :delete %></p> |
25 |
<% else %> |
26 |
<p><%= link_to 'Login', new_admin_session_path %></p> |
27 |
<% end %> |
28 |
</div> |
29 |
</body> |
30 |
</html> |
Jetzt sollten Sie Login / Logout Links auf den Seiten haben, abhängig davon, ob Sie eingeloggt und ausgeloggt sind. Gehen Sie voran und klicken Sie durch die App. Versuchen Sie, nach dem Abmelden auf die neue Buchseite zuzugreifen. Sie sollten eine Fehlermeldung sehen.



Klicken Sie sich durch die App. Sie sollten sich ein- und ausloggen sowie Bücher bearbeiten / erstellen / löschen können. Zeit für den letzten Schritt. Lassen Sie uns Ihre Gedanken und Benutzerkommentare formatieren. Rails hat eine Hilfsmethode, die neue Zeilen in Zeilenumbrüche und diese Sortierung ändert. Fügen Sie diese show.html.erb hinzu:
1 |
|
2 |
# <p><%= @book.thoughts %></p> becomes
|
3 |
<%= simple_format @book.thoughts %> |
4 |
|
5 |
# do the same thing for comments
|
6 |
# <p><strong><%=h(comment.author) %></strong>: <%=h comment.text %> becomes
|
7 |
<p><strong><%=h(comment.author) %></strong>:</p> |
8 |
<%= simple_format comment.text %> |
Es macht keinen Sinn, die Gedanken in den Index zu schreiben, also ersetzen wir das durch eine Vorschau anstelle des gesamten Textes.
1 |
|
2 |
# index.html.erb
|
3 |
# <p><%= book.thoughts %></p> becomes
|
4 |
<%= simple_format(truncate(book.thoughts, 100)) %> |
Jetzt sollte unsere letzte Indexseite so aussehen:



Schließlich müssen wir eine Route für unsere Root-Seite einrichten. Öffnen Sie routes.rb und fügen Sie diese Zeile hinzu:
1 |
|
2 |
map.root :controller => 'books', :action => 'index' |
Wenn Sie jetzt nach / gehen, sehen Sie den Bucheintrag.
Sechzig
Jetzt werden wir diese App in wenigen Schritten bereitstellen. Sie brauchen keinen eigenen Server oder ähnliches. Alles, was Sie brauchen, ist ein Konto bei Heroku. Heroku ist ein Cloud-Rails-Hosting-Service. Wenn Sie eine kleine App haben, können Sie ihren Dienst kostenlos nutzen. Sobald du dich für ein Konto angemeldet hast, installiere das Heroku-Juwel:
1 |
|
2 |
$ sudo gem install heroku |
Heroku arbeitet mit Git. Git ist ein verteiltes Quellcodeverwaltungssystem. Um nach Heroku zu gelangen, musst du nur deine App erstellen und dann deinen Code auf den Server schieben. Wenn Sie git noch nicht installiert haben, finden Sie hier Anleitungen. Sobald Sie heroku und git installiert haben, sind Sie bereit für die Bereitstellung. Als erstes müssen wir ein neues Git Repo aus Ihrem Projekt erstellen:
1 |
|
2 |
bookshelf $ git init |
3 |
Initialized empty Git repository in /Users/adam/Code/bookshelf/.git/ |
Es ist Zeit, Vorbereitungen für die Heroku-Bereitstellung zu treffen. Um die Edelsteine Ihrer Anwendung zu installieren, erstellen Sie eine .gems-Datei im Stammprojektverzeichnis. Jede Zeile hat den Namen des Edelsteins. Wenn Sie Ihren Code auf heroku schieben, liest er die .gems-Datei und installiert die Edelsteine für Sie. Erstellen Sie eine .gems-Datei und fügen Sie diese ein:
1 |
|
2 |
forgery
|
3 |
will_paginate
|
4 |
authlogic
|
Es gibt ein Problem mit Authlogic auf Heroku, daher müssen wir einen Initialisierer erstellen, der den Edelstein für uns benötigt. Erstellen Sie eine neue Datei in /config/initializers/authlogic.rb und fügen Sie diese Zeile ein:
1 |
|
2 |
require 'authlogic' |
Jetzt sollten wir bereit sein zu implementieren. Das erste, was du machen wirst, ist heroku create. Dies wird eine neue Heroku App für Sie erstellen. Wenn Sie zum ersten Mal Benutzer sind, werden Sie durch den Einrichtungsvorgang geführt.
1 |
|
2 |
bookshelf $ heroku create |
3 |
Git remote heroku added |
Nein, wir sind bereit für die Bereitstellung. Hier sind die Schritte
- Fügen Sie alle Dateien im Projekt einem Commit hinzu
- Übernehmen Sie die Dateien
- Push ist Code zu Heroku
- Migrieren Sie die Datenbank auf heroku
- Seed die Datenbank auf Heroku
- Starten Sie den Heroku-Server neu
- Öffnen Sie Ihre laufende Anwendung
1 |
|
2 |
bookshelf $ git add -A |
3 |
bookshelf $ git commit -m 'Initial commit' |
4 |
bookshelf $ git push heroku master |
5 |
bookshelf $ heroku rake db:migrate |
6 |
bookshelf $ heroku rake db:seed |
7 |
bookshelf $ heroku restart |
8 |
bookshelf $ heroku open |
Hier ist die App, die endlich im World Wide Web läuft:
Schlage auf die Bremsen
Wir haben in diesem Artikel eine Menge behandelt, also wo gehen wir von hier aus? Es gibt einige Dinge, die wir in dieser App nicht gemacht haben. Wir haben den Modellen keine Validierungen hinzugefügt. Wir haben keine Teiltöne verwendet. Wir haben keine Administration für die Kommentare gemacht. Dies sind Dinge, die Sie als nächstes betrachten sollten. Hier finden Sie einige Links, die Sie bei den nächsten Schritten unterstützen.
- Abgeschlossener Quellcode
- Verwirrt über die Formteile? Lesen Sie dies
- Verwirrt über Routen? Lesen Sie dies
- Verwirrt über Heroku? Lesen Sie dies
- Verwirrt über Assoziationen? Lesen Sie dies
- Verwirrt über Authlogic? Lesen Sie dies
Links zu Edelsteinen, die in diesem Projekt verwendet werden.
- Folgen Sie uns auf Twitter oder abonnieren Sie den Nettuts + RSS Feed für die besten Tutorials zur Webentwicklung im Internet. Bereit
Sind Sie bereit, Ihre Fähigkeiten auf die nächste Stufe zu heben und von Ihren Skripten und Komponenten zu profitieren? Schauen Sie sich unseren Schwester-Marktplatz CodeCanyon an.
CodeCanyon Schreibe ein Plus-Tutorial
Wussten Sie, dass Sie für das Schreiben eines PLUS-Tutorials und / oder Screencasts für uns bis zu $ 600 verdienen können? Wir suchen nach vertieften und gut geschriebenen Tutorials zu HTML, CSS, PHP und JavaScript. Wenn Sie dazu in der Lage sind, kontaktieren Sie bitte Jeffrey unter nettuts@tutsplus.com.
Bitte beachten Sie, dass die tatsächliche Vergütung von der Qualität des endgültigen Tutorials und Screencasts abhängt.
