Einführung
Ruby on Rails ist ein Webanwendungs-Framework, das in Ruby geschrieben wurde und Entwicklern einen meinungsbasierten Ansatz für die Anwendungsentwicklung bietet. Die Arbeit mit Rails bietet Entwicklern:
- Konventionen für die Handhabung von Dingen wie Routing, zustandsbehafteten Daten und Asset-Verwaltung.
- A firm grounding in the model-view-controller (MCV) architectural pattern, which separates an application’s logic, located in models, from the presentation and routing of application information.
Wenn Sie Komplexität zu Ihren Rails-Anwendungen hinzufügen, werden Sie wahrscheinlich mit mehreren Modellen arbeiten, die die Geschäftslogik Ihrer Anwendung darstellen und mit Ihrer Datenbank interagieren. Das Hinzufügen von verwandten Modellen bedeutet, sinnvolle Beziehungen zwischen ihnen herzustellen, die dann beeinflussen, wie Informationen durch die Controller Ihrer Anwendung übermittelt werden und wie sie von Benutzern durch Ansichten erfasst und präsentiert werden.
In diesem Tutorial werden Sie auf einer bestehenden Rails-Anwendung aufbauen, die Benutzern Fakten über Haie bietet. Diese Anwendung hat bereits ein Modell zur Verarbeitung von Haifischdaten, aber Sie werden eine verschachtelte Ressource für Beiträge über einzelne Haie hinzufügen. Dadurch können Benutzer einen breiteren Gedankenschatz und Meinungen zu einzelnen Haien entwickeln.
Voraussetzungen
Um diesem Tutorial folgen zu können, benötigen Sie:
- A local machine or development server running Ubuntu 18.04. Your development machine should have a non-root user with administrative privileges and a firewall configured with
ufw
. For instructions on how to set this up, see our Initial Server Setup with Ubuntu 18.04 tutorial. - Node.js und npm sind auf Ihrem lokalen Rechner oder Entwicklungsserver installiert. Dieses Tutorial verwendet Node.js Version 10.16.3 und npm Version 6.9.0. Für Anleitungen zur Installation von Node.js und npm unter Ubuntu 18.04 folgen Sie den Anweisungen im Abschnitt „Installation mithilfe eines PPA“ von So installieren Sie Node.js unter Ubuntu 18.04.
- Ruby, rbenv und Rails sind auf Ihrem lokalen Rechner oder Entwicklungsserver installiert, indem Sie Schritte 1-4 in So installieren Sie Ruby on Rails mit rbenv unter Ubuntu 18.04 befolgen. Dieses Tutorial verwendet Ruby 2.5.1, rbenv 1.1.2 und Rails 5.2.3.
- SQLite ist installiert, und eine grundlegende Anwendung für Haie ist erstellt, indem Sie den Anweisungen in So erstellen Sie eine Ruby on Rails-Anwendung folgen.
Schritt 1 — Das verschachtelte Modell scaffolden
Unsere Anwendung wird von den Assoziationen von Active Record profitieren, um eine Beziehung zwischen den Modellen Shark
und Post
aufzubauen: Posts werden bestimmten Haien gehören, und jeder Hai kann mehrere Posts haben. Unsere Modelle Shark
und Post
werden daher über die belongs_to
– und has_many
-Assoziationen miteinander verbunden sein.
Der erste Schritt, um die Anwendung auf diese Weise zu erstellen, wird sein, ein Post
-Modell und zugehörige Ressourcen zu erstellen. Dazu können wir den Befehl rails generate scaffold
verwenden, der uns ein Modell, eine Datenbankmigration zur Änderung des Datenbankschemas, einen Controller, einen vollständigen Satz von Ansichten zum Verwalten der Standard-Erstellen, Lesen, Aktualisieren und Löschen (CRUD)-Operationen sowie Vorlagen für Partials, Helfer und Tests gibt. Wir müssen diese Ressourcen anpassen, aber die Verwendung des Befehls scaffold
wird uns etwas Zeit und Energie sparen, da er eine Struktur generiert, die wir als Ausgangspunkt verwenden können.
Zuerst stellen Sie sicher, dass Sie sich im Verzeichnis sharkapp
für das Rails-Projekt befinden, das Sie in den Voraussetzungen erstellt haben:
Erstellen Sie Ihre Post
-Ressourcen mit folgendem Befehl:
rails generate scaffold Post body:text shark:references
Mit `body:text
` sagen wir Rails, ein body
-Feld in der posts
-Datenbanktabelle einzuschließen – die Tabelle, die zum Post
-Modell abbildet. Wir inkludieren auch das :references
-Schlüsselwort, welches eine Verbindung zwischen den Shark
– und Post
-Modellen einrichtet. Speziell stellt dies sicher, dass ein Fremdschlüssel, der jeden Shark-Eintrag in der sharks
-Datenbank darstellt, zur posts
-Datenbank hinzugefügt wird.
Nachdem du den Befehl ausgeführt hast, wirst du eine Ausgabe sehen, die die Ressourcen bestätigt, die Rails für die Anwendung generiert hat. Bevor du fortfährst, kannst du deine Datenbank-Migrationsdatei überprüfen, um die Beziehung anzusehen, die jetzt zwischen deinen Modellen und Datenbanktabellen besteht. Verwende den folgenden Befehl, um den Inhalt der Datei anzusehen, und achte darauf, den Zeitstempel in deiner eigenen Migrationsdatei für das zu verwenden, was hier gezeigt wird:
Du wirst die folgende Ausgabe sehen:
Outputclass CreatePosts < ActiveRecord::Migration[5.2]
def change
create_table :posts do |t|
t.text :body
t.references :shark, foreign_key: true
t.timestamps
end
end
end
Wie du sehen kannst, enthält die Tabelle eine Spalte für einen Shark-Fremdschlüssel. Dieser Schlüssel wird in Form von model_name_id
vorliegen – in unserem Fall shark_id
.
Rails hat die Beziehung zwischen den Modellen auch anderswo hergestellt. Sieh dir das neu generierte Post
-Modell mit dem folgenden Befehl an:
cat app/models/post.rb
Outputclass Post < ApplicationRecord
belongs_to :shark
end
Die belongs_to
-Assoziation richtet eine Beziehung zwischen Modellen ein, bei der eine einzelne Instanz des deklarierenden Modells zu einer einzelnen Instanz des benannten Modells gehört. In unserem Fall bedeutet dies, dass ein einzelner Beitrag zu einem einzigen Shark gehört.
Zusätzlich zur Festlegung dieser Beziehung hat der Befehl rails generate scaffold
auch Routen und Ansichten für Beiträge erstellt, wie er es auch für unsere Haifisch-Ressourcen in Schritt 3 von Wie man eine Ruby on Rails-Anwendung erstellt getan hat.
Dies ist ein nützlicher Anfang, aber wir müssen einige zusätzliche Routen konfigurieren und die aktive Record-Verknüpfung für das Shark
-Modell festigen, damit die Beziehung zwischen unseren Modellen und Routen wie gewünscht funktioniert.
Schritt 2 — Spezifizierung von Verschachtelten Routen und Verknüpfungen für das Elternmodell
Rails hat bereits die belongs_to
-Verknüpfung in unserem Post
-Modell festgelegt, dank des :references
-Schlüsselworts im rails generate scaffold
-Befehl, aber damit diese Beziehung ordnungsgemäß funktioniert, müssen wir auch eine has_many
-Verknüpfung in unserem Shark
-Modell angeben. Wir müssen auch Änderungen an den Standard-Routen vornehmen, die uns Rails gegeben hat, um Beitrag-Ressourcen zu den Kindern von Haifisch-Ressourcen zu machen.
Um die has_many
-Assoziation zum Modell Shark
hinzuzufügen, öffnen Sie app/models/shark.rb
mit nano
oder Ihrem bevorzugten Editor:
Fügen Sie die folgende Zeile zur Datei hinzu, um die Beziehung zwischen Haien und Beiträgen herzustellen:
class Shark < ApplicationRecord
has_many :posts
validates :name, presence: true, uniqueness: true
validates :facts, presence: true
end
Eine Sache, über die es sich hier nachzudenken lohnt, ist, was mit Beiträgen passiert, wenn ein bestimmter Hai gelöscht wird. Wahrscheinlich möchten wir nicht, dass die Beiträge, die mit einem gelöschten Hai verbunden sind, in der Datenbank bestehen bleiben. Um sicherzustellen, dass alle Beiträge, die mit einem bestimmten Hai verbunden sind, gelöscht werden, wenn dieser Hai gelöscht wird, können wir die dependent
-Option mit der Assoziation einschließen.
Fügen Sie den folgenden Code zur Datei hinzu, um sicherzustellen, dass die destroy
-Aktion bei einem bestimmten Hai alle zugehörigen Beiträge löscht:
class Shark < ApplicationRecord
has_many :posts , dependent: :destroy
validates :name, presence: true, uniqueness: true
validates :facts, presence: true
end
Nachdem Sie diese Änderungen vorgenommen haben, speichern Sie die Datei und schließen Sie sie. Wenn Sie nano
verwenden, können Sie dies tun, indem Sie STRG+X
, Y
, dann ENTER
drücken.
Öffnen Sie als nächstes Ihre config/routes.rb
-Datei, um die Beziehung zwischen Ihren ressourcenorientierten Routen zu ändern:
Derzeit sieht die Datei so aus:
Rails.application.routes.draw do
resources :posts
resources :sharks
root 'sharks#index'
# Weitere Informationen zur verfügbaren DSL in dieser Datei finden Sie unter http://guides.rubyonrails.org/routing.html
end
Der aktuelle Code etabliert eine unabhängige Beziehung zwischen unseren Routen, während wir gerne eine abhängige Beziehung zwischen Haien und ihren zugehörigen Beiträgen ausdrücken möchten.
Lassen Sie uns unsere Routendeklaration aktualisieren, um :sharks
zum Elternteil von :posts
zu machen. Aktualisieren Sie den Code in der Datei wie folgt:
Rails.application.routes.draw do
resources :sharks do
resources :posts
end
root 'sharks#index'
# Weitere Details zur verfügbaren DSL in dieser Datei finden Sie unter http://guides.rubyonrails.org/routing.html
end
Speichern und schließen Sie die Datei, wenn Sie mit der Bearbeitung fertig sind.
Mit diesen Änderungen können Sie damit fortfahren, Ihren posts
-Controller zu aktualisieren.
Schritt 3 — Aktualisierung des Posts-Controllers
Die Verbindung zwischen unseren Modellen gibt uns Methoden, die wir verwenden können, um neue Post-Instanzen zu erstellen, die mit bestimmten Haien verbunden sind. Um diese Methoden zu verwenden, müssen wir sie unserem Posts-Controller hinzufügen.
Öffnen Sie die Datei des Posts-Controllers:
Aktuell sieht die Datei wie folgt aus:
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
# GET /posts
# GET /posts.json
def index
@posts = Post.all
end
# GET /posts/1
# GET /posts/1.json
def show
end
# GET /posts/new
def new
@post = Post.new
end
# GET /posts/1/edit
def edit
end
# POST /posts
# POST /posts.json
def create
@post = Post.new(post_params)
respond_to do |format|
if @post.save
format.html { redirect_to @post, notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: @post }
else
format.html { render :new }
format.json { render json: @post.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /posts/1
# PATCH/PUT /posts/1.json
def update
respond_to do |format|
if @post.update(post_params)
format.html { redirect_to @post, notice: 'Post was successfully updated.' }
format.json { render :show, status: :ok, location: @post }
else
format.html { render :edit }
format.json { render json: @post.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
@post.destroy
respond_to do |format|
format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
@post = Post.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def post_params
params.require(:post).permit(:body, :shark_id)
end
end
Wie unser Controller für Haie arbeitet auch dieser Controller mit Instanzen der zugehörigen Post
-Klasse. Zum Beispiel erstellt die Methode new
eine neue Instanz der Klasse Post
, die Methode index
greift auf alle Instanzen der Klasse zu, und die Methode set_post
verwendet find
und params
, um einen bestimmten Beitrag nach der id
auszuwählen. Wenn wir jedoch möchten, dass unsere Beitragsexemplare mit bestimmten Hai-Exemplaren verbunden sind, müssen wir diesen Code ändern, da die Klasse Post
derzeit als unabhängige Entität fungiert.
Unsere Änderungen werden zwei Dinge nutzen:
- Die Methoden, die uns zur Verfügung stehen, wenn wir die
belongs_to
– undhas_many
-Verknüpfungen zu unseren Modellen hinzugefügt haben. Speziell haben wir jetzt Zugriff auf diebuild
-Methode dank der von uns definiertenhas_many
-Verknüpfung in unseremShark
-Modell. Diese Methode ermöglicht es uns, eine Sammlung von Beitrag-Objekten zu erstellen, die mit einem bestimmten Hai-Objekt verknüpft sind, indem wir denshark_id
-Fremdschlüssel verwenden, der in unsererposts
-Datenbank vorhanden ist. - Die Routen und Routenhelfer, die verfügbar wurden, als wir eine verschachtelte
posts
-Route erstellt haben. Für eine vollständige Liste von Beispielrouten, die verfügbar werden, wenn Sie verschachtelte Beziehungen zwischen Ressourcen erstellen, siehe die Rails-Dokumentation. Für jetzt wird es für uns ausreichen zu wissen, dass für jeden spezifischen Hai — sagen wirsharks/1
— es eine zugehörige Route für Beiträge gibt, die mit diesem Hai verbunden sind:sharks/1/posts
. Es wird auch Routenhelfer wieshark_posts_path(@shark)
undedit_sharks_posts_path(@shark)
geben, die sich auf diese verschachtelten Routen beziehen.
In der Datei werden wir damit beginnen, eine Methode namens get_shark
zu schreiben, die vor jeder Aktion im Controller ausgeführt wird. Diese Methode wird eine lokale @shark
-Instanzvariable erstellen, indem sie eine Hai-Instanz nach shark_id
findet. Mit dieser Variable, die uns in der Datei zur Verfügung steht, wird es möglich sein, Beiträge in den anderen Methoden mit einem bestimmten Hai in Beziehung zu setzen.
Über den anderen private
Methoden am Ende der Datei fügen Sie die folgende Methode hinzu:
. . .
private
def get_shark
@shark = Shark.find(params[:shark_id])
end
# Verwenden Sie Rückrufe, um gemeinsame Einrichtung oder Einschränkungen zwischen Aktionen zu teilen.
. . .
Als nächstes fügen Sie den entsprechenden Filter oben in die Datei ein, bevor der vorhandene Filter hinzugefügt wird:
class PostsController < ApplicationController
before_action :get_shark
Dies stellt sicher, dass get_shark
vor jeder in der Datei definierten Aktion ausgeführt wird.
Als nächstes können Sie diese @shark
-Instanz verwenden, um die index
-Methode neu zu schreiben. Anstatt alle Instanzen der Klasse Post
abzurufen, möchten wir, dass diese Methode alle Postinstanzen zurückgibt, die mit einer bestimmten Haiinstanz verknüpft sind.
Ändern Sie die index
-Methode so:
. . .
def index
@posts = @shark.posts
end
. . .
Die new
-Methode benötigt eine ähnliche Überarbeitung, da wir möchten, dass eine neue Postinstanz mit einem bestimmten Hai verknüpft wird. Um dies zu erreichen, können wir die build
-Methode zusammen mit unserer lokalen @shark
-Instanzvariable verwenden.
Ändern Sie die new
-Methode wie folgt:
. . .
def new
@post = @shark.posts.build
end
. . .
Diese Methode erstellt ein Postobjekt, das mit der spezifischen Haiinstanz aus der get_shark
-Methode verknüpft ist.
Als nächstes werden wir uns der Methode widmen, die am engsten mit new
verbunden ist: create
. Die create
-Methode tut zwei Dinge: Sie erstellt eine neue Postinstanz mit den Parametern, die Benutzer in das new
-Formular eingegeben haben, und wenn keine Fehler auftreten, speichert sie diese Instanz und verwendet einen Routenhelfer, um Benutzer dorthin umzuleiten, wo sie den neuen Beitrag sehen können. Im Falle von Fehlern rendert es das new
-Template erneut.
Aktualisieren Sie die create
-Methode, damit sie so aussieht:
def create
@post = @shark.posts.build(post_params)
respond_to do |format|
if @post.save
format.html { redirect_to shark_posts_path(@shark), notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: @post }
else
format.html { render :new }
format.json { render json: @post.errors, status: :unprocessable_entity }
end
end
end
Als nächstes werfen Sie einen Blick auf die update
-Methode. Diese Methode verwendet eine @post
-Instanzvariable, die nicht explizit in der Methode selbst festgelegt ist. Woher stammt diese Variable?
Schauen Sie sich die Filter oben in der Datei an. Der zweite, automatisch generierte before_action
-Filter liefert eine Antwort:
class PostsController < ApplicationController
before_action :get_shark
before_action :set_post, only: [:show, :edit, :update, :destroy]
. . .
Die update
-Methode (wie show
, edit
und destroy
) nimmt eine @post
-Variable aus der set_post
-Methode. Diese Methode, aufgeführt unter der get_shark
-Methode mit unseren anderen private
-Methoden, sieht derzeit so aus:
. . .
private
. . .
def set_post
@post = Post.find(params[:id])
end
. . .
Im Einklang mit den Methoden, die wir anderswo in der Datei verwendet haben, müssen wir diese Methode ändern, damit @post
auf eine bestimmte Instanz in der Sammlung von Posts verweist, die mit einem bestimmten Hai verbunden ist. Behalten Sie hier die build
-Methode im Hinterkopf – dank der Beziehungen zwischen unseren Modellen und den Methoden (wie build
), die uns durch diese Beziehungen zur Verfügung stehen, ist jede unserer Postinstanzen Teil einer Sammlung von Objekten, die mit einem bestimmten Hai verbunden ist. Es ergibt also Sinn, dass wir beim Abfragen eines bestimmten Posts die Sammlung von Posts abfragen, die mit einem bestimmten Hai verbunden ist.
Aktualisieren Sie set_post
, damit es so aussieht:
. . .
private
. . .
def set_post
@post = @shark.posts.find(params[:id])
end
. . .
Anstatt eine bestimmte Instanz der gesamten Post
-Klasse nach id
zu suchen, suchen wir stattdessen nach einer übereinstimmenden id
in der Sammlung von Posts, die mit einem bestimmten Hai verbunden ist.
Mit dieser aktualisierten Methode können wir uns die update
und destroy
Methoden ansehen.
Die update
Methode verwendet die @post
Instanzvariable von set_post
und verwendet sie mit den post_params
, die der Benutzer im edit
Formular eingegeben hat. Im Erfolgsfall möchten wir, dass Rails den Benutzer zur index
Ansicht der Beiträge eines bestimmten Hais zurücksendet. Im Fehlerfall rendert Rails erneut das edit
Template.
In diesem Fall müssen wir nur die redirect_to
Anweisung ändern, um erfolgreiche Updates zu behandeln. Aktualisieren Sie sie so, dass sie zu shark_post_path(@shark)
umleitet, was zur index
Ansicht der Beiträge des ausgewählten Hais umleitet:
. . .
def update
respond_to do |format|
if @post.update(post_params)
format.html { redirect_to shark_post_path(@shark), notice: 'Post was successfully updated.' }
format.json { render :show, status: :ok, location: @post }
else
format.html { render :edit }
format.json { render json: @post.errors, status: :unprocessable_entity }
end
end
end
. . .
Als nächstes machen wir eine ähnliche Änderung an der destroy
Methode. Aktualisieren Sie die redirect_to
Methode, um Anfragen im Erfolgsfall an shark_posts_path(@shark)
umzuleiten:
. . .
def destroy
@post.destroy
respond_to do |format|
format.html { redirect_to shark_posts_path(@shark), notice: 'Post was successfully destroyed.' }
format.json { head :no_content }
end
end
. . .
Dies ist die letzte Änderung, die wir vornehmen werden. Sie haben jetzt eine Post-Controller-Datei, die folgendermaßen aussieht:
class PostsController < ApplicationController
before_action :get_shark
before_action :set_post, only: [:show, :edit, :update, :destroy]
# GET /posts
# GET /posts.json
def index
@posts = @shark.posts
end
# GET /posts/1
# GET /posts/1.json
def show
end
# GET /posts/new
def new
@post = @shark.posts.build
end
# GET /posts/1/edit
def edit
end
# POST /posts
# POST /posts.json
def create
@post = @shark.posts.build(post_params)
respond_to do |format|
if @post.save
format.html { redirect_to shark_posts_path(@shark), notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: @post }
else
format.html { render :new }
format.json { render json: @post.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /posts/1
# PATCH/PUT /posts/1.json
def update
respond_to do |format|
if @post.update(post_params)
format.html { redirect_to shark_post_path(@shark), notice: 'Post was successfully updated.' }
format.json { render :show, status: :ok, location: @post }
else
format.html { render :edit }
format.json { render json: @post.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
@post.destroy
respond_to do |format|
format.html { redirect_to shark_posts_path(@shark), notice: 'Post was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def get_shark
@shark = Shark.find(params[:shark_id])
end
# Use callbacks to share common setup or constraints between actions.
def set_post
@post = @shark.posts.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def post_params
params.require(:post).permit(:body, :shark_id)
end
end
Der Controller verwaltet, wie Informationen zwischen den Ansichtsvorlagen und der Datenbank übergeben werden und umgekehrt. Unser Controller spiegelt nun die Beziehung zwischen unseren Modellen Shark
und Post
wider, bei der Posts mit bestimmten Haien verbunden sind. Wir können nun damit fortfahren, die Ansichtsvorlagen selbst zu ändern, in denen Benutzer Postinformationen zu bestimmten Haien eingeben und ändern.
Schritt 4 — Ansichten anpassen
Unsere Überarbeitung der Ansichtsvorlagen beinhaltet die Änderung der Vorlagen, die sich auf Posts beziehen, und die Modifikation unserer Haiansicht show
, da wir möchten, dass Benutzer die mit bestimmten Haien verbundenen Posts sehen.
Beginnen wir mit der grundlegenden Vorlage für unsere Posts: dem form
-Partial, das in mehreren Post-Vorlagen wiederverwendet wird. Öffnen Sie dieses Formular jetzt:
Anstatt nur das post
-Modell dem form_with
-Formularhelfer zu übergeben, geben wir sowohl die Modelle shark
als auch post
weiter, wobei post
als untergeordnete Ressource festgelegt ist.
Ändern Sie die erste Zeile der Datei so, dass sie wie folgt aussieht, um die Beziehung zwischen unseren Hai- und Post-Ressourcen widerzuspiegeln:
<%= form_with(model: [@shark, post], local: true) do |form| %>
. . .
Löschen Sie als Nächstes den Abschnitt, der die shark_id
des zugehörigen Hais auflistet, da diese Information in der Ansicht nicht wesentlich ist.
Das fertige Formular, komplett mit unseren Bearbeitungen der ersten Zeile und ohne den gelöschten Abschnitt shark_id
, wird wie folgt aussehen:
<%= form_with(model: [@shark, post], local: true) do |form| %>
<% if post.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(post.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% post.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :body %>
<%= form.text_area :body %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
Speichern Sie die Datei und schließen Sie sie, wenn Sie mit der Bearbeitung fertig sind.
Öffnen Sie als Nächstes die Ansicht index
, die die mit einem bestimmten Hai verbundenen Beiträge anzeigt:
Dank des Befehls rails generate scaffold
hat Rails den Großteil der Vorlage generiert, komplett mit einer Tabelle, die das Feld body
jedes Beitrags und seinen zugehörigen shark
anzeigt.
Wie bei dem anderen Code, den wir bereits geändert haben, behandelt diese Vorlage jedoch Beiträge als unabhängige Entitäten, während wir die Beziehungen zwischen unseren Modellen und die Sammlungen und Hilfsmethoden nutzen möchten, die uns diese Beziehungen geben.
Aktualisieren Sie im Tabellenkörper Folgendes:
Ersetzen Sie zunächst post.shark
durch post.shark.name
, damit die Tabelle das Namensfeld des zugehörigen Hais enthält, anstatt Informationen über das Hai-Objekt selbst zu identifizieren:
. . .
<tbody>
<% @posts.each do |post| %>
<tr>
<td><%= post.body %></td>
<td><%= post.shark.name %></td>
. . .
Als nächstes ändern Sie die Umleitung von Show
, um Benutzer zur show
-Ansicht des zugehörigen Haies zu führen, da sie wahrscheinlich einen Weg zurück zum ursprünglichen Hai wünschen werden. Wir können die @shark
-Instanzvariable nutzen, die wir hier im Controller gesetzt haben, da Rails Instanzvariablen, die im Controller erstellt wurden, allen Ansichten zur Verfügung stellt. Wir ändern auch den Text für den Link von Show
auf Hai anzeigen
, damit Benutzer seine Funktion besser verstehen.
Aktualisieren Sie diese Zeile wie folgt:
. . .
<tbody>
<% @posts.each do |post| %>
<tr>
<td><%= post.body %></td>
<td><%= post.shark.name %></td>
<td><%= link_to 'Show Shark', [@shark] %></td>
In der nächsten Zeile möchten wir sicherstellen, dass Benutzer den richtigen verschachtelten Pfad geroutet bekommen, wenn sie einen Beitrag bearbeiten. Das bedeutet, dass Benutzer nicht zu posts/post_id/edit
weitergeleitet werden, sondern zu sharks/shark_id/posts/post_id/edit
. Dazu verwenden wir den Routing-Helfer shark_post_path
und unsere Modelle, die Rails als URLs behandeln wird. Wir aktualisieren auch den Linktext, um seine Funktion klarer zu machen.
Aktualisieren Sie die Zeile Edit
wie folgt:
. . .
<tbody>
<% @posts.each do |post| %>
<tr>
<td><%= post.body %></td>
<td><%= post.shark.name %></td>
<td><%= link_to 'Show Shark', [@shark] %></td>
<td><%= link_to 'Edit Post', edit_shark_post_path(@shark, post) %></td>
Als nächstes fügen wir eine ähnliche Änderung zum Löschen
-Link hinzu, aktualisieren seine Funktion in der Zeichenkette und fügen unsere Ressourcen shark
und post
hinzu:
. . .
<tbody>
<% @posts.each do |post| %>
<tr>
<td><%= post.body %></td>
<td><%= post.shark.name %></td>
<td><%= link_to 'Show Shark', [@shark] %></td>
<td><%= link_to 'Edit Post', edit_shark_post_path(@shark, post) %></td>
<td><%= link_to 'Destroy Post', [@shark, post], method: :delete, data: { confirm: 'Are you sure?' } %></td>
Zuletzt möchten wir am Ende des Formulars den Pfad Neuer Beitrag
aktualisieren, um Benutzer zum entsprechenden verschachtelten Pfad zu führen, wenn sie einen neuen Beitrag erstellen möchten. Aktualisieren Sie die letzte Zeile der Datei, um den Routing-Helfer new_shark_post_path(@shark)
zu verwenden:
. . .
<%= link_to 'New Post', new_shark_post_path(@shark) %>
Die fertige Datei wird wie folgt aussehen:
<p id="notice"><%= notice %></p>
<h1>Posts</h1>
<table>
<thead>
<tr>
<th>Body</th>
<th>Shark</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% @posts.each do |post| %>
<tr>
<td><%= post.body %></td>
<td><%= post.shark.name %></td>
<td><%= link_to 'Show Shark', [@shark] %></td>
<td><%= link_to 'Edit Post', edit_shark_post_path(@shark, post) %></td>
<td><%= link_to 'Destroy Post', [@shark, post], method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Post', new_shark_post_path(@shark) %>
Speichern Sie die Datei und schließen Sie sie, wenn Sie mit der Bearbeitung fertig sind.
Die anderen Änderungen, die wir an den Beitragansichten vornehmen werden, werden nicht so zahlreich sein, da unsere anderen Ansichten das bereits bearbeitete form
-Partial verwenden. Wir möchten jedoch die link_to
-Verweise in den anderen Beitragstemplates aktualisieren, um die Änderungen, die wir an unserem form
-Partial vorgenommen haben, widerzuspiegeln.
Öffnen Sie app/views/posts/new.html.erb
:
Aktualisieren Sie den link_to
-Verweis am Ende der Datei, um den shark_posts_path(@shark)
-Helfer zu verwenden:
. . .
<%= link_to 'Back', shark_posts_path(@shark) %>
Speichern Sie die Datei und schließen Sie sie, wenn Sie diese Änderung abgeschlossen haben.
Öffnen Sie als nächstes das Bearbeiten
-Template:
Neben dem Zurück
-Pfad aktualisieren wir Anzeigen
, um unsere verschachtelten Ressourcen widerzuspiegeln. Ändern Sie die letzten beiden Zeilen der Datei so:
. . .
<%= link_to 'Show', [@shark, @post] %> |
<%= link_to 'Back', shark_posts_path(@shark) %>
Speichern und schließen Sie die Datei.
Öffnen Sie als nächstes das Anzeigen
-Template:
nano app/views/posts/show.html.erb
Führen Sie folgende Änderungen am Bearbeiten
– und Zurück
-Pfad am Ende der Datei durch:
. . .
<%= link_to 'Edit', edit_shark_post_path(@shark, @post) %> |
<%= link_to 'Back', shark_posts_path(@shark) %>
Speichern Sie die Datei und schließen Sie sie, wenn Sie fertig sind.
Als letzten Schritt möchten wir die Anzeigen
-Ansicht für unsere Haie aktualisieren, damit Beiträge für einzelne Haie sichtbar sind. Öffnen Sie jetzt diese Datei:
Unsere Änderungen hier umfassen das Hinzufügen eines Beiträge
-Abschnitts zum Formular und einen Beitrag hinzufügen
-Link am Ende der Datei.
Unterhalb der Facts
für einen bestimmten Hai werden wir einen neuen Abschnitt hinzufügen, der durch jede Instanz in der Sammlung von Beiträgen dieses Haies iteriert und den body
jedes Beitrags ausgibt.
Fügen Sie den folgenden Code unterhalb des Facts
-Abschnitts des Formulars und über den Weiterleitungen am Ende der Datei hinzu:
. . .
<p>
<strong>Facts:</strong>
<%= @shark.facts %>
</p>
<h2>Posts</h2>
<% for post in @shark.posts %>
<ul>
<li><%= post.body %></li>
</ul>
<% end %>
<%= link_to 'Edit', edit_shark_path(@shark) %> |
. . .
Fügen Sie als nächstes eine neue Weiterleitung hinzu, damit Benutzer einen neuen Beitrag für diesen bestimmten Hai hinzufügen können:
. . .
<%= link_to 'Edit', edit_shark_path(@shark) %> |
<%= link_to 'Add Post', shark_posts_path(@shark) %> |
<%= link_to 'Back', sharks_path %>
Speichern und schließen Sie die Datei, wenn Sie mit der Bearbeitung fertig sind.
Sie haben nun Änderungen an den Modellen, Controllern und Ansichten Ihrer Anwendung vorgenommen, um sicherzustellen, dass Beiträge immer mit einem bestimmten Hai verknüpft sind. Als letzter Schritt können wir einige Validierungen zu unserem Post
-Modell hinzufügen, um die Konsistenz der Daten zu gewährleisten, die in die Datenbank gespeichert werden.
Schritt 5 — Validierungen hinzufügen und die Anwendung testen
Im Schritt 5 von Wie man eine Ruby on Rails Anwendung erstellt, haben Sie Validierungen zu Ihrem Shark
-Modell hinzugefügt, um Einheitlichkeit und Konsistenz in den Daten sicherzustellen, die in die sharks
-Datenbank gespeichert werden. Nun werden wir einen ähnlichen Schritt unternehmen, um Garantien für die posts
-Datenbank sicherzustellen.
Öffnen Sie die Datei, in der Ihr Post
-Modell definiert ist:
Hier möchten wir sicherstellen, dass Beiträge nicht leer sind und dass sie keine doppelten Inhalte enthalten, die andere Benutzer möglicherweise gepostet haben. Um dies zu erreichen, fügen Sie die folgende Zeile zur Datei hinzu:
class Post < ApplicationRecord
belongs_to :shark
validates :body, presence: true, uniqueness: true
end
Speichern Sie die Datei und schließen Sie sie, wenn Sie mit der Bearbeitung fertig sind.
Mit dieser letzten Änderung sind Sie bereit, Ihre Migrationen auszuführen und die Anwendung zu testen.
Führen Sie zuerst Ihre Migrationen aus:
Starten Sie anschließend Ihren Server. Wenn Sie lokal arbeiten, können Sie dies tun, indem Sie folgendes ausführen:
Wenn Sie auf einem Entwicklungsserver arbeiten, führen Sie stattdessen den folgenden Befehl aus:
Navigieren Sie zu Ihrem Anwendungsstamm unter http://localhost:3000
oder http://Ihre_Server_IP:3000
.
Das vorherige Rails-Projekt-Tutorial führte Sie durch das Hinzufügen und Bearbeiten eines Weißen Hais-Eintrags. Wenn Sie keine weiteren Haie hinzugefügt haben, wird die Startseite der Anwendung folgendermaßen aussehen:
Klicken Sie auf Anzeigen neben dem Namen des Great White. Dadurch gelangen Sie zur Anzeigen
-Ansicht für diesen Hai. Sie sehen den Namen des Haies und seine Fakten sowie einen Beiträge-Header ohne Inhalt. Fügen wir einen Beitrag hinzu, um diesen Teil des Formulars auszufüllen.
Klicken Sie unter dem Beiträge-Header auf Beitrag hinzufügen. Dadurch gelangen Sie zur Beitrag Index
-Ansicht, wo Sie die Möglichkeit haben, Neuer Beitrag auszuwählen:
Dank der Authentifizierungsmechanismen, die Sie in Schritt 6 von So erstellen Sie eine Ruby on Rails-Anwendung implementiert haben, kann es sein, dass Sie aufgefordert werden, sich mit dem Benutzernamen und dem Passwort, die Sie in diesem Schritt erstellt haben, zu authentifizieren, abhängig davon, ob Sie eine neue Sitzung erstellt haben oder nicht.
Klicken Sie auf Neuer Beitrag, um zu Ihrer Beitrag Neu
-Vorlage zu gelangen:
Geben Sie im Inhalt-Feld „Diese Haie sind gruselig!“ ein.
Klicken Sie auf Beitrag erstellen. Sie werden zur Index
-Ansicht für alle Beiträge, die zu diesem Hai gehören, weitergeleitet:
Mit unseren Beitrag-Ressourcen funktioniert, können wir jetzt unsere Datenvalidierungen testen, um sicherzustellen, dass nur gewünschte Daten in die Datenbank gespeichert werden.
Von der Index
-Ansicht aus klicken Sie auf Neuer Beitrag. Geben Sie im Inhalt-Feld des neuen Formulars erneut „Diese Haie sind gruselig!“ ein:
Klicken Sie auf Beitrag erstellen. Sie werden den folgenden Fehler sehen:
Klicken Sie auf Zurück, um zur Hauptseite der Beiträge zurückzukehren.
Um unsere andere Validierung zu testen, klicken Sie erneut auf Neuer Beitrag. Lassen Sie den Beitrag leer und klicken Sie auf Beitrag erstellen. Sie werden den folgenden Fehler sehen:
Mit Ihren verschachtelten Ressourcen und Validierungen, die ordnungsgemäß funktionieren, haben Sie jetzt eine funktionierende Rails-Anwendung, die Sie als Ausgangspunkt für weitere Entwicklung verwenden können.
Abschluss
Mit Ihrer Rails-Anwendung können Sie jetzt an Dingen wie Styling und der Entwicklung anderer Frontend-Komponenten arbeiten. Wenn Sie mehr über Routing und verschachtelte Ressourcen erfahren möchten, ist die Rails-Dokumentation ein großartiger Ausgangspunkt.
Um mehr über die Integration von Frontend-Frameworks in Ihre Anwendung zu erfahren, werfen Sie einen Blick auf Wie man ein Ruby-on-Rails-Projekt mit einem React-Frontend einrichtet.