So erstellen Sie verschachtelte Ressourcen für eine Ruby on Rails-Anwendung

Einführung

Ruby on Rails ist ein in Ruby geschriebenes Webanwendungsframework, das Entwicklern einen einsichtigen Ansatz für die Anwendungsentwicklung bietet. Die Arbeit mit Rails bietet Entwicklern:

  • Konventionen für den Umgang mit Routing, statusbehafteten Daten und Asset Management.

  • Eine feste Grundlage im Architekturmuster model-view-controller (MCV), das die Logik einer Anwendung trennt in Modellen aus der Präsentation und Weiterleitung von Anwendungsinformationen.

Wenn Sie Ihre Rails-Anwendungen komplexer gestalten, werden Sie wahrscheinlich mit mehreren Modellen arbeiten, die die Geschäftslogik Ihrer Anwendung und die Schnittstelle zu Ihrer Datenbank darstellen. Wenn Sie verwandte Modelle hinzufügen, müssen Sie sinnvolle Beziehungen zwischen ihnen herstellen, die sich darauf auswirken, wie Informationen über die Controller Ihrer Anwendung weitergeleitet werden und wie sie erfasst und den Benutzern über Ansichten wiedergegeben werden.

In diesem Tutorial bauen Sie auf einer vorhandenen Rails-Anwendung auf, die Benutzern Fakten zu Haien bietet. Diese Anwendung verfügt bereits über ein Modell für den Umgang mit Hai-Daten. Sie fügen jedoch eine verschachtelte Ressource für Posts zu einzelnen Haien hinzu. Auf diese Weise können Benutzer ein breiteres Spektrum an Gedanken und Meinungen zu einzelnen Haien aufbauen.

Voraussetzungen

Um diesem Tutorial zu folgen, benötigen Sie:

  • Ein lokaler Computer oder Entwicklungsserver, auf dem Ubuntu 18.04 ausgeführt wird. Ihr Entwicklungscomputer sollte einen Nicht-Root-Benutzer mit Administratorrechten und eine mit "+ ufw +" konfigurierte Firewall haben. Anweisungen zum Einrichten finden Sie in unserem Initial Server Setup with Ubuntu 18.04 Tutorial.

  • https://nodejs.org [Node.js] und npm, die auf Ihrem lokalen Computer oder Entwicklungsserver installiert sind. In diesem Tutorial werden die Versionen Node.js und npm verwendet. Anleitungen zum Installieren von Node.js und npm unter Ubuntu 18.04 finden Sie unter https://www.digitalocean.com/community/tutorials/how-to-install-node-js-. on-ubuntu-18-04 # installation-using-a-ppa [Installieren von Node.js unter Ubuntu 18.04].

  • Ruby, rbenv und Rails, die auf Ihrem lokalen Computer oder Entwicklungsserver installiert sind. Befolgen Sie dazu die Schritte 1 bis 4 unter https://www.digitalocean.com/community/tutorials/how- ruby-on-rail-with-rbenv-on-ubuntu-18-04 installieren [Wie installiert man Ruby on Rails mit rbenv unter Ubuntu 18.04]. Dieses Tutorial verwendet Ruby, rbenv und Rails.

  • SQLite wurde installiert und eine grundlegende Hai-Informationsanwendung erstellt, die den Anweisungen unter How To Build a Ruby folgt on Rails-Anwendung.

Schritt 1 - Gerüste des verschachtelten Modells

Unsere Anwendung nutzt Active Record associations, um eine Beziehung zwischen den Modellen "+ Shark " und " Post " herzustellen: Die Pfosten gehören bestimmten Haien und jedem Hai kann mehrere Beiträge haben. Unsere Modelle ` Shark ` und ` Post ` werden daher über https://guides.rubyonrails.org/association_basics.html#the-belongs-to-association [` belong_to `] und https: // guides miteinander verknüpft. rubyonrails.org/association_basics.html#the-has-many-association [` has_many +`] Associations.

Der erste Schritt zum Erstellen der Anwendung auf diese Weise besteht darin, ein "+ Post " - Modell und zugehörige Ressourcen zu erstellen. Zu diesem Zweck können wir den Befehl " Rails generieren Gerüst " verwenden, der uns ein Modell gibt: https://guides.rubyonrails.org/active_record_migrations.html[database migration], um das Datenbankschema, einen Controller, zu ändern. einen vollständigen Satz von Ansichten zum Verwalten der Standardoperationen https://en.wikipedia.org/wiki/[Create, Read, Update and Delete] (CRUD) sowie Vorlagen für Teilversuche, Hilfsprogramme und Tests. Wir müssen diese Ressourcen ändern, aber die Verwendung des Befehls " scaffold +" spart Zeit und Energie, da eine Struktur erstellt wird, die wir als Ausgangspunkt verwenden können.

Stellen Sie zunächst sicher, dass Sie sich im Verzeichnis "+ sharkapp +" für das Rails-Projekt befinden, das Sie unter den folgenden Voraussetzungen erstellt haben:

cd sharkapp

Erstellen Sie Ihre + Post + Ressourcen mit dem folgenden Befehl:

rails generate scaffold Post body:text shark:references

Mit "+ body: text " weisen wir Rails an, ein Feld " body " in die Datenbanktabelle " posts " aufzunehmen - die Tabelle, die dem Modell " Post " zugeordnet ist. Wir schließen auch das Schlüsselwort ": references " ein, das eine Zuordnung zwischen den Modellen " Shark " und " Post " herstellt. Dies stellt insbesondere sicher, dass ein https://en.wikipedia.org/wiki/Foreign_key[foreign key], der jeden Haieintrag in der Datenbank " sharks " darstellt, zur Datenbank " posts +" hinzugefügt wird.

Sobald Sie den Befehl ausgeführt haben, wird in der Ausgabe bestätigt, welche Ressourcen Rails für die Anwendung generiert hat. Bevor Sie fortfahren, können Sie in Ihrer Datenbankmigrationsdatei die Beziehung überprüfen, die jetzt zwischen Ihren Modellen und Datenbanktabellen besteht. Verwenden Sie den folgenden Befehl, um den Inhalt der Datei zu überprüfen, und stellen Sie sicher, dass der Zeitstempel in Ihrer eigenen Migrationsdatei durch den hier gezeigten ersetzt wird:

cat db/migrate/_create_posts.rb

Sie werden die folgende Ausgabe sehen:

Outputclass CreatePosts < ActiveRecord::Migration[5.2]
 def change
   create_table :posts do |t|
     t.text :body


     t.timestamps
   end
 end
end

Wie Sie sehen, enthält die Tabelle eine Spalte für einen Haifisch-Fremdschlüssel. Dieser Schlüssel hat die Form "+ _id " - in unserem Fall " _id +".

Rails hat die Beziehung zwischen den Modellen auch an anderer Stelle hergestellt. Sehen Sie sich das neu generierte + Post + Modell mit dem folgenden Befehl an:

cat app/models/post.rb
Outputclass Post < ApplicationRecord
 belongs_to :shark
end

Die Assoziation "+ belong_to +" stellt eine Beziehung zwischen Modellen her, in denen eine einzelne Instanz des deklarierenden Modells zu einer einzelnen Instanz des benannten Modells gehört. Bei unserer Anwendung bedeutet dies, dass ein einzelner Pfosten zu einem einzelnen Hai gehört.

Zusätzlich zum Festlegen dieser Beziehung wurden mit dem Befehl "+ Schienen + Gerüst erstellen" auch Routen und Ansichten für Posts erstellt, wie dies für unsere Hai-Ressourcen unter https://www.digitalocean.com/community/tutorials/how-to-build der Fall war -a-ruby-on-rail-anwendung # step-3-% E2% 80% 94-scaffolding-the-application [Step 3] von https://www.digitalocean.com/community/tutorials/how-to- Erstellen einer Ruby-on-Rails-Anwendung [So erstellen Sie eine Ruby-on-Rails-Anwendung].

Dies ist ein nützlicher Anfang, aber wir müssen ein zusätzliches Routing konfigurieren und die Active Record-Zuordnung für das Modell "+ Shark +" festigen, damit die Beziehung zwischen unseren Modellen und Routen wie gewünscht funktioniert.

Schritt 2 - Angeben von verschachtelten Routen und Zuordnungen für das übergeordnete Modell

Rails hat in unserem Modell "+ Post " bereits die Assoziation " belong_to " festgelegt, dank des Schlüsselworts ": references " im Befehl " rails generate scaffold ". Damit diese Beziehung jedoch ordnungsgemäß funktioniert, müssen wir dies tun Geben Sie eine " has_many " Assoziation auch in unserem " Shark +" Modell an. Wir müssen auch Änderungen am Standardrouting vornehmen, das Rails uns gegeben hat, um die Postressourcen zu den Kindern der Hairessourcen zu machen.

Um die Assoziation "+ has_many " zum Modell " Shark " hinzuzufügen, öffnen Sie " app / models / shark.rb " mit " nano +" oder Ihrem bevorzugten Editor:

nano app/models/shark.rb

Fügen Sie der Datei die folgende Zeile hinzu, um die Beziehung zwischen Haien und Pfählen herzustellen:

~ / sharkapp / app / models / shark.rb

class Shark < ApplicationRecord

 validates :name, presence: true, uniqueness: true
 validates :facts, presence: true
end

Eine Sache, über die man nachdenken sollte, ist, was mit Beiträgen passiert, wenn ein bestimmter Hai gelöscht wird. Wir möchten wahrscheinlich nicht, dass die Posts, die mit einem gelöschten Hai verknüpft sind, in der Datenbank verbleiben. Um sicherzustellen, dass Beiträge, die einem bestimmten Hai zugeordnet sind, gelöscht werden, wenn dieser Hai gelöscht wird, können wir der Zuordnung die Option "+ abhängig +" hinzufügen.

Fügen Sie der Datei den folgenden Code hinzu, um sicherzustellen, dass die Aktion "+ destroy +" für einen bestimmten Hai alle zugehörigen Beiträge löscht:

~ / sharkapp / app / models / post.rb

class Shark < ApplicationRecord
 has_many :posts
 validates :name, presence: true, uniqueness: true
 validates :facts, presence: true
end

Wenn Sie diese Änderungen vorgenommen haben, speichern und schließen Sie die Datei. Wenn Sie "+ nano " verwenden, können Sie dies tun, indem Sie " STRG + X ", " Y " und dann " ENTER +" drücken.

Öffnen Sie als Nächstes Ihre Datei "+ config / routes.rb +", um die Beziehung zwischen Ihren einfallsreichen Routen zu ändern:

nano config/routes.rb

Derzeit sieht die Datei folgendermaßen aus:

~ / sharkapp / config / routes.rb

Rails.application.routes.draw do
 resources :posts
 resources :sharks

 root 'sharks#index'
 # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

Der aktuelle Code stellt eine unabhängige Beziehung zwischen unseren Routen her, wenn wir eine dependent relationship zwischen Haien und den zugehörigen Posts ausdrücken möchten.

Aktualisieren wir unsere Routendeklaration, um ": sharks +" zum übergeordneten Element von ": posts +" zu machen. Aktualisieren Sie den Code in der Datei so, dass er wie folgt aussieht:

~ / sharkapp / config / routes.rb

Rails.application.routes.draw do
 resources
   resources

 root 'sharks#index'
 # For details on the DSL available within this file, see 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 fortfahren, um Ihre + posts + Controller zu aktualisieren.

Schritt 3 - Aktualisieren des Posts Controllers

Die Assoziation zwischen unseren Modellen gibt uns Methoden, mit denen wir neue Post-Instanzen erstellen können, die bestimmten Haien zugeordnet sind. Um diese Methoden zu verwenden, müssen wir sie unserem Post-Controller hinzufügen.

Öffne die posts controller Datei:

nano app/controllers/posts_controller.rb

Derzeit sieht die Datei folgendermaßen aus:

~ / sharkapp / controller / posts_controller.rb

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 Hai-Controller funktionieren die Methoden dieses Controllers mit Instanzen der zugeordneten Klasse "+ Post ". Beispielsweise erstellt die Methode " new " eine neue Instanz der Klasse " Post ", die Methode " index " erfasst alle Instanzen der Klasse, und die Methode " set_post " verwendet " find " und " params " `um einen bestimmten Beitrag mit` + id + `auszuwählen. Wenn wir jedoch möchten, dass unsere Post-Instanzen bestimmten Shark-Instanzen zugeordnet werden, müssen wir diesen Code ändern, da die Klasse " Post +" derzeit als unabhängige Entität arbeitet.

Unsere Modifikationen werden zwei Dinge nutzen:

  • Die Methoden, die uns zur Verfügung standen, als wir unseren Modellen die Assoziationen + belong_to + und + has_many + hinzufügten. Insbesondere haben wir jetzt Zugriff auf die https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many [+ build + method] dank der von uns definierten + has_many + Assoziation in unserem + Shark + Modell. Mit dieser Methode können wir eine Sammlung von Post-Objekten erstellen, die einem bestimmten Shark-Objekt zugeordnet sind, indem wir den in unserer Datenbank vorhandenen Fremdschlüssel "+ shark_id +" verwenden.

  • Die Routen und Routing-Hilfsprogramme, die verfügbar wurden, als wir eine verschachtelte "+ posts " - Route erstellt haben. Eine vollständige Liste der Beispielrouten, die verfügbar werden, wenn Sie verschachtelte Beziehungen zwischen Ressourcen erstellen, finden Sie in der Dokumentation zu https://guides.rubyonrails.org/routing.html#nested-resources[Rails]. Fürs Erste wird es ausreichen, zu wissen, dass es für jeden bestimmten Hai - sagen wir " sharks / " - eine zugehörige Route für Beiträge zu diesem Hai gibt: " sharks // posts ". Es wird auch Routing-Helfer wie ` shark_posts_path (@shark) ` und ` edit_sharks_posts_path (@shark) +` geben, die auf diese verschachtelten Routen verweisen.

In der Datei schreiben wir zunächst eine Methode "+ get_shark ", die vor jeder Aktion im Controller ausgeführt wird. Diese Methode erstellt eine lokale Instanzvariable " @ shark ", indem sie eine Hai-Instanz mit " shark_id +" findet. Mit dieser Variablen, die uns in der Datei zur Verfügung steht, ist es möglich, Beiträge mit einem bestimmten Hai in den anderen Methoden zu verknüpfen.

Fügen Sie über den anderen "+ private +" - Methoden am Ende der Datei die folgende Methode hinzu:

~ / sharkapp / controller / posts_controller.rb

. . .
private



 # Use callbacks to share common setup or constraints between actions.
. . .

Fügen Sie als Nächstes den entsprechenden Filter am * Anfang * der Datei vor dem vorhandenen Filter hinzu:

~ / sharkapp / controller / posts_controller.rb

class PostsController < ApplicationController

Dadurch wird sichergestellt, 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 umzuschreiben. Anstatt alle Instanzen der Klasse "+ Post +" zu erfassen, soll diese Methode alle Post-Instanzen zurückgeben, die einer bestimmten Hai-Instanz zugeordnet sind.

Ändern Sie die Methode + index + so, dass sie wie folgt aussieht:

~ / sharkapp / controller / posts_controller.rb

. . .
 def index
   @posts =
 end
. . .

Die Methode + new + benötigt eine ähnliche Überarbeitung, da eine neue Post-Instanz mit einem bestimmten Hai verknüpft werden soll. Um dies zu erreichen, können wir die Methode "+ build " zusammen mit unserer lokalen Instanzvariablen " @ shark +" verwenden.

Ändern Sie die + new + Methode so:

~ / sharkapp / controller / posts_controller.rb

. . .
 def new
   @post =
 end
. . .

Diese Methode erstellt aus der Methode "+ get_shark +" ein Post-Objekt, das der bestimmten Hai-Instanz zugeordnet ist.

Als nächstes befassen wir uns mit der Methode, die am ehesten mit "+ new" zusammenhängt: "+ create". Die Methode "+ create " führt zwei Dinge aus: Sie erstellt eine neue Post-Instanz unter Verwendung der Parameter, die Benutzer in das Formular " new " eingegeben haben. Wenn keine Fehler vorliegen, speichert sie diese Instanz und leitet sie mit einem Routen-Helfer um Benutzer, wo sie den neuen Beitrag sehen können. Im Fehlerfall wird die Vorlage ` new +` erneut gerendert.

Aktualisieren Sie die Methode + create + folgendermaßen:

~ / sharkapp / controller / posts_controller.rb

 def create
   @post = (post_params)

       respond_to do |format|
        if @post.save
           format.html { redirect_to , 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

Schauen Sie sich als nächstes die Methode "+ update" an. Diese Methode verwendet eine Instanzvariable + @ post +, die in der Methode selbst nicht explizit festgelegt ist. Woher kommt diese Variable?

Schauen Sie sich die Filter oben in der Datei an. Der zweite, automatisch generierte "+ before_action +" - Filter liefert eine Antwort:

~ / sharkapp / controller / posts_controller.rb

class PostsController < ApplicationController
 before_action :get_shark
 before_action :set_post, only: [:show, :edit, :update, :destroy]
 . . .

Die Methode "+ update " (wie " show ", " edit " und " destroy") verwendet eine Variable "+ @ post " aus der Methode " set_post ". Diese Methode, die unter der Methode " get_shark " mit unseren anderen Methoden " private +" aufgeführt ist, sieht derzeit folgendermaßen aus:

~ / sharkapp / controller / posts_controller.rb

. . .
private
. . .
 def set_post
   @post = Post.find(params[:id])
 end
. . .

In Übereinstimmung mit den Methoden, die wir an anderer Stelle in der Datei verwendet haben, müssen wir diese Methode so ändern, dass "+ @ post " auf eine bestimmte Instanz in der * Sammlung * von Posts verweist, die einem bestimmten Hai zugeordnet sind. Beachten Sie dabei die Methode " build " - dank der Verknüpfungen zwischen unseren Modellen und den Methoden (wie " build +"), die uns aufgrund dieser Verknüpfungen zur Verfügung stehen, ist jede unserer Post-Instanzen Teil einer Sammlung von Objekten, die mit einem bestimmten Hai verbunden sind. Wenn wir nach einem bestimmten Beitrag fragen, ist es daher sinnvoll, die Sammlung der Beiträge abzufragen, die einem bestimmten Hai zugeordnet sind.

Aktualisiere + set_post + so, dass es so aussieht:

~ / sharkapp / controller / posts_controller.rb

. . .
private
. . .
 def set_post
   @post = (params[:id])
 end
. . .

Anstatt eine bestimmte Instanz der gesamten Klasse "+ Post " anhand von " id " zu finden, suchen wir stattdessen nach einer übereinstimmenden " id +" in der Sammlung von Posts, die einem bestimmten Hai zugeordnet sind.

Wenn diese Methode aktualisiert ist, können wir uns die Methoden "+ update" und "+ destroy" ansehen.

Die Methode "+ update " verwendet die Instanzvariable " @ post " aus " set_post " und verwendet sie mit " post_params ", die der Benutzer in das Formular " edit " eingegeben hat. Im Erfolgsfall möchten wir, dass Rails den Benutzer zurück zur Ansicht " index " der Beiträge sendet, die mit einem bestimmten Hai verknüpft sind. Im Fehlerfall rendert Rails die Vorlage ` edit +` erneut.

In diesem Fall müssen wir nur die Anweisung "+ redirect_to " ändern, um erfolgreiche Aktualisierungen durchführen zu können. Aktualisieren Sie es, um zu " shark_post_path (@shark) " umzuleiten. Dadurch wird zur " index +" - Ansicht der Beiträge des ausgewählten Hais umgeleitet:

~ / sharkapp / controller / posts_controller.rb

. . .
 def update
   respond_to do |format|
     if @post.update(post_params)
       format.html { redirect_to , 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 nehmen wir eine ähnliche Änderung an der Methode "+ destroy " vor. Aktualisieren Sie die Methode " redirect_to ", um bei Erfolg Anfragen an " shark_posts_path (@shark) +" umzuleiten:

~ / sharkapp / controller / posts_controller.rb

. . .
 def destroy
   @post.destroy
    respond_to do |format|
     format.html { redirect_to , 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 Posts-Controller-Datei, die folgendermaßen aussieht:

~ / sharkapp / controller / posts_controller.rb

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 von den Ansichtsvorlagen an die Datenbank und umgekehrt übergeben werden. Unser Controller spiegelt nun die Beziehung zwischen unseren Modellen "+ Shark " und " Post +" wider, bei denen Pfosten bestimmten Haien zugeordnet sind. Wir können die Ansichtsvorlagen selbst ändern. Dort werden Benutzer Informationen zu bestimmten Haien eingeben und ändern.

Schritt 4 - Ansichten ändern

Unsere Überarbeitungen der Ansichtsvorlagen umfassen das Ändern der Vorlagen, die sich auf Beiträge beziehen, sowie das Ändern unserer Hai-Ansicht „+ show +“, da wir möchten, dass Benutzer die Beiträge sehen, die bestimmten Haien zugeordnet sind.

Beginnen wir mit der grundlegenden Vorlage für unsere Posts: dem Teil "+ form +", der für mehrere Post-Vorlagen wiederverwendet wird. Öffnen Sie das Formular jetzt:

nano app/views/posts/_form.html.erb

Anstatt nur das "+ post " - Modell an den " form_with " - Formularhelfer zu übergeben, übergeben wir sowohl das " shark " - als auch das " post " - Modell, wobei " post +" als untergeordnete Ressource festgelegt ist.

Ändern Sie die erste Zeile der Datei so, dass sie wie folgt aussieht:

~ / sharkapp / views / posts / _form.html.erb

<%= form_with(model: , local: true) do |form| %>
. . .

Als nächstes * löschen * Sie den Abschnitt, der die + shark_id + des verwandten Hais auflistet, da dies keine wesentlichen Informationen in der Ansicht sind.

Das fertige Formular sieht mit unseren Änderungen in der ersten Zeile und ohne den gelöschten Abschnitt + shark_id + folgendermaßen aus:

~ / sharkapp / views / posts / _form.html.erb

<%= 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 und schließen Sie die Datei, wenn Sie mit der Bearbeitung fertig sind.

Öffnen Sie als Nächstes die Ansicht "+ index +", in der die mit einem bestimmten Hai verknüpften Beiträge angezeigt werden:

nano app/views/posts/index.html.erb

Dank des Befehls "+ Schienen generieren Gerüst " hat Rails den größten Teil der Vorlage generiert, einschließlich einer Tabelle, die das Feld " Körper " jedes Pfostens und das zugehörige Feld " Hai +" anzeigt.

Ähnlich wie der andere Code, den wir bereits geändert haben, behandelt diese Vorlage Beiträge jedoch als unabhängige Entitäten, wenn wir die Verknüpfungen zwischen unseren Modellen und den Sammlungen und Hilfsmethoden nutzen möchten, die diese Verknüpfungen uns geben.

Nehmen Sie im Hauptteil der Tabelle die folgenden Aktualisierungen vor:

Aktualisieren Sie zuerst + post.shark + zu + post.shark.name +, sodass die Tabelle das Namensfeld des zugeordneten Hais enthält, anstatt Informationen über das Haiobjekt selbst zu identifizieren:

~ / sharkapp / app / views / posts / index.html.erb

. . .
 <tbody>
   <% @posts.each do |post| %>
     <tr>
       <td><%= post.body %></td>
       <td><%= post.shark %></td>
. . .

Ändern Sie als Nächstes die Weiterleitung "+ Show", um Benutzer zur Ansicht "+ Show s" für den zugeordneten Hai zu leiten, da sie höchstwahrscheinlich eine Möglichkeit möchten, zum ursprünglichen Hai zurückzukehren. Wir können die Instanzvariable + @ shark + verwenden, die wir hier im Controller setzen, da Rails im Controller erstellte Instanzvariablen für alle Views zur Verfügung stellt. Wir werden auch den Text für den Link von "+ Show" in "+ Show Shark" ändern, damit die Benutzer die Funktion besser verstehen.

Aktualisieren Sie diese Zeile wie folgt:

~ / sharkapp / app / views / posts / index.html.erb

. . .
 <tbody>
   <% @posts.each do |post| %>
     <tr>
       <td><%= post.body %></td>
       <td><%= post.shark.name %></td>
       <td><%= link_to 'Show ',  %></td>

In der nächsten Zeile möchten wir sicherstellen, dass Benutzer den richtigen verschachtelten Pfad erhalten, wenn sie einen Beitrag bearbeiten. Das bedeutet, dass Benutzer nicht zu "+ posts // edit " geleitet werden, sondern zu " sharks // posts // edit ". Dazu verwenden wir den Routing-Helfer " shark_post_path +" und unsere Modelle, die Rails als URLs behandelt. Wir aktualisieren auch den Linktext, um die Funktion klarer zu gestalten.

Aktualisieren Sie die Zeile + Edit + so, dass sie wie folgt aussieht:

~ / sharkapp / app / views / posts / index.html.erb

. . .
 <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 ',  %></td>

Als Nächstes fügen wir dem Link "+ Zerstören " eine ähnliche Änderung hinzu, aktualisieren seine Funktion in der Zeichenfolge und fügen unsere Ressourcen " Hai " und " Post +" hinzu:

~ / sharkapp / app / views / posts / index.html.erb

. . .
 <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 ', , method: :delete, data: { confirm: 'Are you sure?' } %></td>

Schließlich möchten wir am Ende des Formulars den Pfad "+ New Post " 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:

~ / sharkapp / app / views / posts / index.html.erb

. . .
<%= link_to 'New Post',  %>

Die fertige Datei sieht folgendermaßen aus:

~ / sharkapp / app / views / posts / index.html.erb

<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 und schließen Sie die Datei, wenn Sie mit der Bearbeitung fertig sind.

Die anderen Bearbeitungen, die wir zum Posten von Ansichten vornehmen, sind nicht so zahlreich, da in unseren anderen Ansichten das von uns bereits bearbeitete "+ form " - Teil verwendet wird. Wir möchten jedoch die Verweise auf " link_to " in den anderen Beitragsvorlagen aktualisieren, um die Änderungen widerzuspiegeln, die wir an unserem " form +" - Teil vorgenommen haben.

Öffne + app / views / posts / new.html.erb +:

nano app/views/posts/new.html.erb

Aktualisieren Sie die Referenz "+ link_to " am Ende der Datei, um den Helfer " shark_posts_path (@shark) +" zu verwenden:

~ / sharkapp / app / views / posts / new.html.erb

. . .
<%= link_to 'Back',  %>

Speichern und schließen Sie die Datei, wenn Sie mit der Änderung fertig sind.

Öffnen Sie als nächstes die Vorlage + edit +:

nano app/views/posts/edit.html.erb

Zusätzlich zum + Back Puth aktualisieren wir` + How`, um unsere verschachtelten Ressourcen widerzuspiegeln. Ändern Sie die letzten beiden Zeilen der Datei so:

~ / sharkapp / app / views / posts / edit.html.erb

. . .
<%= link_to 'Show',  %> |
<%= link_to 'Back',  %>

Speichern und schließen Sie die Datei.

Öffnen Sie als nächstes die Vorlage "+ show +":

nano app/views/posts/show.html.erb

Nehmen Sie die folgenden Änderungen an den Pfaden "+ Bearbeiten " und " Zurück +" am Ende der Datei vor:

~ / sharkapp / app / views / posts / edit.html.erb

. . .
<%= link_to 'Edit',  %> |
<%= link_to 'Back',  %>

Speichern und schließen Sie die Datei, wenn Sie fertig sind.

Als letzten Schritt wollen wir die "+ show +" - Ansicht für unsere Haie aktualisieren, so dass Beiträge für einzelne Haie sichtbar sind. Öffne diese Datei jetzt:

nano app/views/sharks/show.html.erb

Zu unseren Bearbeitungen hier gehört das Hinzufügen eines Abschnitts "+ Posts " zum Formular und eines Links " Add Post +" am Ende der Datei.

Unterhalb der "+ Facts " für einen bestimmten Hai fügen wir einen neuen Abschnitt hinzu, der die einzelnen Instanzen in der Sammlung der mit diesem Hai verknüpften Posts durchläuft und den " body +" jedes Posts ausgibt.

Fügen Sie den folgenden Code unter dem Abschnitt "+ Facts +" des Formulars und über den Weiterleitungen am Ende der Datei ein:

~ / sharkapp / app / views / sharks / show.html.erb

. . .
<p>
 <strong>Facts:</strong>
 <%= @shark.facts %>
</p>








<%= link_to 'Edit', edit_shark_path(@shark) %> |
. . .

Fügen Sie als Nächstes eine neue Umleitung hinzu, damit Benutzer einen neuen Beitrag für diesen bestimmten Hai hinzufügen können:

~ / sharkapp / app / views / sharks / show.html.erb

. . .
<%= link_to 'Edit', edit_shark_path(@shark) %> |

<%= link_to 'Back', sharks_path %>

Speichern und schließen Sie die Datei, wenn Sie mit der Bearbeitung fertig sind.

Sie haben nun die Modelle, Controller und Ansichten Ihrer Anwendung geändert, um sicherzustellen, dass die Pfosten immer mit einem bestimmten Hai verknüpft sind. Als letzten Schritt können wir unserem "+ Post +" - Modell einige Validierungen hinzufügen, um die Konsistenz der in der Datenbank gespeicherten Daten zu gewährleisten.

Schritt 5 - Hinzufügen von Validierungen und Testen der Anwendung

In Step 5 von Wie man eine Ruby on Rails-Anwendung erstellt, haben Sie Validierungen zu Ihrem + Shark + - Modell hinzugefügt um die Einheitlichkeit und Konsistenz der Daten zu gewährleisten, die in der "+ sharks " - Datenbank gespeichert werden. Wir werden jetzt einen ähnlichen Schritt unternehmen, um Garantien auch für die Datenbank " posts +" zu gewährleisten.

Öffnen Sie die Datei, in der Ihr + Post + Modell definiert ist:

nano app/models/post.rb

Hier möchten wir sicherstellen, dass Beiträge nicht leer sind und keine Inhalte duplizieren, die andere Benutzer möglicherweise gepostet haben. Fügen Sie dazu der Datei die folgende Zeile hinzu:

~ / sharkapp / app / models / post.rb

class Post < ApplicationRecord
 belongs_to :shark

end

Speichern und schließen Sie die Datei, wenn Sie mit der Bearbeitung fertig sind.

Mit dieser letzten Änderung können Sie Ihre Migrationen ausführen und die Anwendung testen.

Führen Sie zunächst Ihre Migrationen aus:

rails db:migrate

Starten Sie als nächstes Ihren Server. Wenn Sie lokal arbeiten, können Sie dazu Folgendes ausführen:

rails s

Wenn Sie auf einem Entwicklungsserver arbeiten, führen Sie stattdessen den folgenden Befehl aus:

rails s --binding=

Navigieren Sie zum Stammverzeichnis Ihrer Anwendung unter "+ http: // localhost: 3000 " oder " http: //: 3000 +".

Das vorausgesetzte Rails-Projekt-Tutorial führte Sie durch das Hinzufügen und Bearbeiten eines * Great White * -Eintrags. Wenn Sie keine weiteren Haie hinzugefügt haben, sieht die Zielseite der Anwendung folgendermaßen aus:

image: https: //assets.digitalocean.com/articles/rails_nested_resource/shark_post_landing_2.png [Landing Page der Shark App]

Klicken Sie neben dem Namen des * Great White * auf * Anzeigen *. Hiermit gelangen Sie zur Ansicht "+ show +" für diesen Hai. Sie sehen den Namen des Hais und seine Fakten sowie einen * Posts * -Header ohne Inhalt. Fügen wir einen Beitrag hinzu, um diesen Teil des Formulars auszufüllen.

Klicken Sie auf * Beitrag hinzufügen * unter der Überschrift * Beiträge *. Hiermit gelangen Sie zur Ansicht "+ Index +", in der Sie die Möglichkeit haben, "Neuer Beitrag" auszuwählen:

image: https: //assets.digitalocean.com/articles/rails_nested_resource/new_post_landing.png [Indexansicht]

Dank der Authentifizierungsmechanismen, die Sie in https://www.digitalocean.com/community/tutorials/how-to-build-a-ruby-on-rails-application#step-6--%E2%80% eingerichtet haben 94-Hinzufügen-Authentifizierung [Schritt 6] von https://www.digitalocean.com/community/tutorials/anwendungsbeschreibung zum Erstellen von Ruby-on-Rails-Anwendungen], Je nachdem, ob Sie eine neue Sitzung erstellt haben oder nicht, werden Sie möglicherweise aufgefordert, sich mit dem Benutzernamen und dem Kennwort zu authentifizieren, die Sie in diesem Schritt erstellt haben.

Klicken Sie auf * New Post *, um zu Ihrem Beitrag zu gelangen. + New + template:

image: https: //assets.digitalocean.com/articles/rails_nested_resource/new_post_form.png [Neuer Beitrag]

Geben Sie im Feld * Körper * Folgendes ein: "Diese Haie sind gruselig!"

image: https: //assets.digitalocean.com/articles/rails_nested_resource/new_shark_post_2.png [New Shark Post]

Klicken Sie auf * Beitrag erstellen *. Sie werden für alle Beiträge, die zu diesem Hai gehören, zur Ansicht "+ index +" weitergeleitet:

image: https: //assets.digitalocean.com/articles/rails_nested_resource/post_success.png [Post Success]

Nachdem unsere Post-Ressourcen verfügbar sind, können wir jetzt unsere Datenvalidierungen testen, um sicherzustellen, dass nur die gewünschten Daten in der Datenbank gespeichert werden.

Klicken Sie in der Ansicht "+ Index +" auf "Neuer Beitrag". Geben Sie im Feld * Körper * des neuen Formulars erneut "Diese Haie sind gruselig!" Ein:

image: https: //assets.digitalocean.com/articles/rails_nested_resource/new_shark_post_2.png [Wiederhole Shark Post]

Klicken Sie auf * Beitrag erstellen *. Sie werden den folgenden Fehler sehen:

image: https: //assets.digitalocean.com/articles/rails_nested_resource/post_unique_error.png [Unique Post Error]

Klicken Sie auf * Zurück *, um zur Hauptseite zurückzukehren.

Um unsere andere Validierung zu testen, klicken Sie erneut auf * New Post *. Lassen Sie den Beitrag leer und klicken Sie auf "Beitrag erstellen". Sie werden den folgenden Fehler sehen:

image: https: //assets.digitalocean.com/articles/rails_nested_resource/post_blank_error.png

Wenn Ihre verschachtelten Ressourcen und Validierungen ordnungsgemäß funktionieren, steht Ihnen jetzt eine funktionsfähige Rails-Anwendung zur Verfügung, die Sie als Ausgangspunkt für die weitere Entwicklung verwenden können.

Fazit

Mit Ihrer Rails-Anwendung können Sie jetzt beispielsweise an der Gestaltung und Entwicklung anderer Front-End-Komponenten arbeiten. Wenn Sie mehr über Routing und verschachtelte Ressourcen erfahren möchten, ist die Rails documentation ein guter Ausgangspunkt.

Weitere Informationen zum Integrieren von Front-End-Frameworks in Ihre Anwendung finden Sie unter https://www.digitalocean.com/community/tutorials/how-to-set-up-a-ruby-on-rails-project-with -a-react-frontend [So richten Sie ein Ruby on Rails-Projekt mit einem React-Frontend ein].