Comment créer des ressources imbriquées pour une application Ruby on Rails

introduction

Ruby on Rails est un cadre d’application Web écrit à l’adresse Ruby qui offre aux développeurs une approche avisée du développement d’applications. Travailler avec Rails offre aux développeurs:

  • Conventions pour gérer des éléments tels que le routage, les données avec état et la gestion des actifs.

  • Une base solide dans le modèle architectural model-view-controller (MCV), qui sépare la logique d’une application, située dans les modèles, à partir de la présentation et du routage des informations d’application.

À mesure que vous ajouterez de la complexité à vos applications Rails, vous travaillerez probablement avec plusieurs modèles, qui représentent la logique métier de votre application et son interface avec votre base de données. Ajouter des modèles associés signifie établir des relations significatives entre eux, ce qui affecte ensuite la manière dont les informations sont relayées par les contrôleurs de votre application et comment elles sont capturées et présentées aux utilisateurs via des vues.

Dans ce didacticiel, vous allez développer une application Rails existante offrant aux utilisateurs des informations sur les requins. Cette application possède déjà un modèle pour la gestion des données de requin, mais vous allez ajouter une ressource imbriquée pour les publications sur les requins individuels. Cela permettra aux utilisateurs de créer un ensemble plus large d’idées et d’opinions sur les requins.

Conditions préalables

Pour suivre ce tutoriel, vous aurez besoin de:

  • Une machine locale ou un serveur de développement exécutant Ubuntu 18.04. Votre machine de développement doit avoir un utilisateur non root avec des privilèges d’administration et un pare-feu configuré avec + ufw +. Pour savoir comment configurer cela, consultez notre tutoriel https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-18-04 (Configuration initiale du serveur avec Ubuntu 18.04]).

  • https://nodejs.org [Node.js] et npm installés sur votre ordinateur local ou votre serveur de développement. Ce tutoriel utilise la version Node.js et la version npm. Pour obtenir des conseils sur l’installation de Node.js et de npm sur Ubuntu 18.04, suivez les instructions de la section «Installation à l’aide de PPA» de la page https://www.digitalocean.com/community/tutorials/how-to-install-node-js- on-ubuntu-18-04 # installation-using-a-ppa [Comment installer Node.js sur Ubuntu 18.04].

  • Ruby, rbenv et Rails installés sur votre ordinateur local ou votre serveur de développement, en suivant les étapes 1 à 4 de la https://www.digitalocean.com/community/tutorials/how- installer-ruby-on-rails-with-rbenv-on-ubuntu-18-04 [Comment installer Ruby sur des rails avec rbenv sur Ubuntu 18.04]. Ce tutoriel utilise Ruby, Rbenv et Rails.

  • SQLite installé et une application de base d’informations sur les requins créée en suivant les instructions fournies à l’adresse Comment créer un rubis sur l’application Rails.

Étape 1 - Échafaudage du modèle imbriqué

Notre application tirera parti d’Active Record associations pour créer une relation entre les modèles + Shark + et + Post +: chacun appartiendra à un requin donné, et chaque Le requin peut avoir plusieurs posts. Nos modèles + Shark + et + Post + seront donc reliés entre eux par https://guides.rubyonrails.org/association_basics.html#the-belongs-to-association [+ appartient_to +] et https: // guides. rubyonrails.org/association_basics.html#the-has-many-association [+ has_many +]].

La première étape pour créer l’application de cette manière consistera à créer un modèle + Post + et les ressources associées. Pour ce faire, nous pouvons utiliser la commande + rails generate scaffold +, qui nous donnera un modèle, un database migration pour modifier le schéma de base de données, un contrôleur, un ensemble complet de vues permettant de gérer les opérations CRUD (Create, Lecture, Mise à jour et Suppression, ainsi que des modèles pour les partiels, les assistants et les tests. Nous aurons besoin de modifier ces ressources, mais l’utilisation de la commande + scaffold + nous fera gagner du temps et de l’énergie, car elle génère une structure que nous pouvons utiliser comme point de départ.

Tout d’abord, assurez-vous que vous vous trouvez dans le répertoire + sharkapp + du projet Rails que vous avez créé dans les conditions préalables:

cd sharkapp

Créez vos ressources + Post + avec la commande suivante:

rails generate scaffold Post body:text shark:references

Avec + body: text +, nous demandons à Rails d’inclure un champ + body + dans la table de base de données + posts + - la table qui correspond au modèle + Post +. Nous incluons également le mot-clé +: references +, qui établit une association entre les modèles + Shark + et + Post +. En particulier, cela garantira qu’une clé foreign représentant chaque entrée de requin dans la base de données + sharks + est ajoutée à la base de données + posts +.

Une fois que vous avez exécuté la commande, vous verrez un résultat confirmant les ressources générées par Rails pour l’application. Avant de poursuivre, vous pouvez consulter votre fichier de migration de base de données pour examiner la relation qui existe maintenant entre vos modèles et les tables de base de données. Utilisez la commande suivante pour examiner le contenu du fichier, en veillant à substituer l’horodatage de votre propre fichier de migration à ce qui est indiqué ici:

cat db/migrate/_create_posts.rb

Vous verrez la sortie suivante:

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


     t.timestamps
   end
 end
end

Comme vous pouvez le constater, la table comprend une colonne pour une clé étrangère de requin. Cette clé se présentera sous la forme + _id + - dans notre cas, + _id +.

Rails a également établi la relation entre les modèles. Jetez un coup d’œil au modèle + Post + récemment généré à l’aide de la commande suivante:

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

L’association + appartient_à + établit une relation entre les modèles dans laquelle une seule instance du modèle déclarant appartient à une seule instance du modèle nommé. Dans le cas de notre candidature, cela signifie qu’un seul poste appartient à un seul requin.

En plus de définir cette relation, les commandes + rails généré d’échafaudage + ont également créé des itinéraires et des vues pour les publications, comme pour nos ressources de requin dans https://www.digitalocean.com/community/tutorials/how-to-build -a-ruby-on-rails-application # step-3-% E2% 80% 94-scaffolding-the-application [Étape 3] de https://www.digitalocean.com/community/tutorials/how-to- build-a-ruby-on-rails-application [Comment construire une application Ruby on Rails].

C’est un début utile, mais nous devrons configurer un routage supplémentaire et solidifier l’association Active Record pour le modèle + Shark + afin que la relation entre nos modèles et les routes fonctionne comme souhaité.

Étape 2 - Spécification des itinéraires et associations imbriqués pour le modèle parent

Rails a déjà défini l’association + appartient_à + dans notre modèle + Post +, grâce au mot clé +: references + de la commande + rails générer l’échafaudage +, mais pour que cette relation fonctionne correctement, nous devons spécifiez également une association + has_many + dans notre modèle + Shark +. Nous devrons également modifier le routage par défaut que Rails nous a fourni afin que les ressources de publication soient les enfants des ressources de requin.

Pour ajouter l’association + has_many + au modèle + Shark +, ouvrez + app / models / shark.rb + en utilisant + nano + ou votre éditeur favori:

nano app/models/shark.rb

Ajoutez la ligne suivante au fichier pour établir la relation entre les requins et les publications:

~ / sharkapp / app / models / shark.rb

class Shark < ApplicationRecord

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

Une chose à laquelle il convient de penser ici est ce qui arrive aux publications une fois qu’un requin particulier est supprimé. Nous ne souhaitons probablement pas que les publications associées à un requin supprimé persistent dans la base de données. Pour vous assurer que toutes les publications associées à un requin donné sont éliminées lorsque ce requin est supprimé, nous pouvons inclure l’option + dépendante + avec l’association.

Ajoutez le code suivant au fichier pour vous assurer que l’action + destroy + sur un requin donné supprime toutes les publications associées:

~ / sharkapp / app / models / post.rb

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

Une fois ces modifications effectuées, enregistrez et fermez le fichier. Si vous utilisez + nano +, vous pouvez le faire en appuyant sur + CTRL + X +, + Y +, puis + ENTER +.

Ensuite, ouvrez votre fichier + config / routes.rb + pour modifier la relation entre vos routes sources:

nano config/routes.rb

Actuellement, le fichier ressemble à ceci:

~ / 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

Le code actuel établit une relation indépendante entre nos itinéraires, lorsque nous souhaitons exprimer une relation https://guides.rubyonrails.org/routing.html#nested-resources[dépendance entre les requins et leurs publications associées.

Mettons à jour notre déclaration de route pour faire de +: sharks + le parent de +: posts + `. Mettez à jour le code dans le fichier pour qu’il ressemble à ce qui suit:

~ / 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

Enregistrez et fermez le fichier une fois l’édition terminée.

Avec ces changements en place, vous pouvez passer à la mise à jour de votre contrôleur + posts +.

Étape 3 - Mise à jour du contrôleur de postes

L’association entre nos modèles nous fournit des méthodes que nous pouvons utiliser pour créer de nouvelles instances de publication associées à des requins particuliers. Pour utiliser ces méthodes, nous devrons les ajouter à notre contrôleur de publication.

Ouvrez le fichier du contrôleur de postes:

nano app/controllers/posts_controller.rb

Actuellement, le fichier ressemble à ceci:

~ / sharkapp / controllers / 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

Comme notre contrôleur sharks, les méthodes de ce contrôleur fonctionnent avec des instances de la classe + Post + associée. Par exemple, la méthode new + crée une nouvelle instance de la classe + Post +, la méthode + index + saisit toutes les occurrences de la classe et la méthode + set_post + utilise + find + et + + params + pour sélectionner un message particulier par + id + . Si, toutefois, nous souhaitons que nos instances de publication soient associées à des instances de requin particulières, nous devrons alors modifier ce code, car la classe `+ Post + fonctionne actuellement en tant qu’entité indépendante.

Nos modifications vont utiliser deux choses:

  • Les méthodes qui sont devenues disponibles lorsque nous avons ajouté les associations + appartient_à + et + has_many + à nos modèles. Plus précisément, nous avons maintenant accès à la https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many [+ build +]] grâce à l’association + has_many + que nous avons définie dans notre modèle + Shark +. Cette méthode nous permettra de créer une collection d’objets de publication associés à un objet de requin particulier, en utilisant la clé étrangère + shark_id + qui existe dans notre base de données + posts +.

  • Les itinéraires et les aides au routage qui sont devenus disponibles lorsque nous avons créé un itinéraire imbriqué + posts +. Pour obtenir une liste complète des exemples d’itinéraires disponibles lorsque vous créez des relations imbriquées entre des ressources, voir la documentation Rails. Pour le moment, il nous suffira de savoir que pour chaque requin spécifique - disons + sharks / + - il y aura un itinéraire associé pour les messages liés à ce requin: + sharks // posts +. Il y aura aussi des aides au routage comme + shark_posts_path (@shark) + et + edit_sharks_posts_path (@shark) + qui font référence à ces routes imbriquées.

Dans le fichier, nous allons commencer par écrire une méthode, + get_shark +, qui sera exécutée avant chaque action dans le contrôleur. Cette méthode créera une variable d’instance locale + @ shark + en trouvant une instance de requin avec + shark_id +. Avec cette variable disponible dans le fichier, il sera possible de relier les publications à un requin spécifique dans les autres méthodes.

Au-dessus des autres méthodes + private + en bas du fichier, ajoutez la méthode suivante:

~ / sharkapp / controllers / posts_controller.rb

. . .
private



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

Ensuite, ajoutez le filtre correspondant au * top * du fichier, avant le filtre existant:

~ / sharkapp / controllers / posts_controller.rb

class PostsController < ApplicationController

Cela garantira que + get_shark + sera exécuté avant chaque action définie dans le fichier.

Ensuite, vous pouvez utiliser cette instance + @ shark + pour réécrire la méthode + index +. Au lieu de récupérer toutes les instances de la classe + Post +, nous voulons que cette méthode retourne toutes les instances de publication associées à une instance de requin particulière.

Modifiez la méthode + index pour qu’elle ressemble à ceci:

~ / sharkapp / controllers / posts_controller.rb

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

La méthode new + aura besoin d’une révision similaire, car nous voulons qu’une nouvelle instance de publication soit associée à un requin particulier. Pour ce faire, nous pouvons utiliser la méthode + build +, ainsi que notre variable d’instance locale + @ shark +.

Changez la méthode + new + pour ressembler à ceci:

~ / sharkapp / controllers / posts_controller.rb

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

Cette méthode crée un objet de publication associé à l’instance de requin spécifique à partir de la méthode + get_shark +.

Ensuite, nous aborderons la méthode la plus étroitement liée à + ​​new:` + create`. La méthode + create + fait deux choses: elle construit une nouvelle instance de publication en utilisant les paramètres que les utilisateurs ont entrés dans le formulaire` new + et les utilisateurs à l’endroit où ils peuvent voir le nouveau message. En cas d’erreur, il restitue le modèle `new +.

Mettez à jour la méthode + create + pour qu’elle ressemble à ceci:

~ / sharkapp / controllers / 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

Ensuite, jetez un oeil à la méthode + update +. Cette méthode utilise une variable d’instance + @ post +, qui n’est pas explicitement définie dans la méthode elle-même. D’où vient cette variable?

Regardez les filtres en haut du fichier. Le second filtre + before_action + généré automatiquement fournit une réponse:

~ / sharkapp / controllers / posts_controller.rb

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

La méthode + update + (comme + show +, + edit + et + destroy`) prend une variable + @ post + de la méthode + set_post +. Cette méthode, listée sous la méthode + get_shark + avec nos autres méthodes + private +, ressemble actuellement à ceci:

~ / sharkapp / controllers / posts_controller.rb

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

Conformément aux méthodes que nous avons utilisées ailleurs dans le fichier, nous devrons modifier cette méthode afin que + @ post + fasse référence à une instance particulière de la * collection * de publications associée à un requin particulier. Gardez à l’esprit la méthode + build + - grâce aux associations entre nos modèles et aux méthodes (comme + build +) qui nous sont disponibles grâce à ces associations, chacune de nos instances de publication fait partie d’une collection. d’objets associés à un requin particulier. Il est donc logique que lors de la recherche d’une publication particulière, nous interrogions la collection de publications associées à un requin particulier.

Mettez à jour + set_post + pour ressembler à ceci:

~ / sharkapp / controllers / posts_controller.rb

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

Au lieu de rechercher une instance particulière de la classe + Post + entière par + id +, nous recherchons plutôt un + id + correspondant dans la collection de publications associées à un requin particulier.

Avec cette méthode mise à jour, nous pouvons examiner les méthodes + update et` + destroy`.

La méthode + update + utilise la variable d’instance + @ post + de + set_post + et l’utilise avec les + post_params + que l’utilisateur a entrées dans le formulaire + edit +. En cas de succès, nous voulons que Rails renvoie l’utilisateur à la vue + index + des publications associées à un requin particulier. En cas d’erreur, Rails rendra à nouveau le modèle + edit +.

Dans ce cas, le seul changement que nous devrons apporter concerne l’instruction + redirect_to +, pour gérer les mises à jour réussies. Mettez-le à jour pour le rediriger vers + shark_post_path (@shark) +, qui redirigera vers la vue + index + des messages du requin sélectionné:

~ / sharkapp / controllers / 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
. . .

Ensuite, nous apporterons une modification similaire à la méthode + destroy +. Mettez à jour la méthode + redirect_to + pour rediriger les demandes vers + shark_posts_path (@shark) + en cas de succès:

~ / sharkapp / controllers / 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
. . .

C’est le dernier changement que nous ferons. Vous avez maintenant un fichier de contrôleur de posts qui ressemble à ceci:

~ / sharkapp / controllers / 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

Le contrôleur gère la manière dont les informations sont transmises des modèles de vues à la base de données et inversement. Notre contrôleur reflète maintenant la relation entre nos modèles + Shark + et + Post +, dans lesquels les publications sont associées à des requins particuliers. Nous pouvons passer à la modification des modèles de vue eux-mêmes, qui permettent aux utilisateurs de passer et de modifier les informations de publication relatives à des requins particuliers.

Étape 4 - Modification des vues

Les révisions de notre modèle de vue impliqueront de modifier les modèles liés aux publications, ainsi que de modifier notre vue + show + des requins, car nous souhaitons que les utilisateurs voient les publications associées à des requins particuliers.

Commençons par le modèle de base de nos publications: le partiel + form + qui est réutilisé dans plusieurs modèles de publication. Ouvrez ce formulaire maintenant:

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

Plutôt que de transmettre uniquement le modèle + post + à l’assistant de formulaire + form_with +, nous allons passer les modèles + shark + et + post +, avec + post + défini comme ressource enfant.

Modifiez la première ligne du fichier pour qu’elle ressemble à ceci, reflétant la relation entre nos ressources de requin et de publication:

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

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

Ensuite, * delete * la section qui répertorie le + shark_id + du requin associé, car il ne s’agit pas d’informations essentielles dans la vue.

Le formulaire terminé, complété de nos modifications sur la première ligne et sans la section + shark_id + supprimée, ressemblera à ceci:

~ / 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 %>

Enregistrez et fermez le fichier une fois l’édition terminée.

Ensuite, ouvrez la vue + index +, qui affichera les publications associées à un requin particulier:

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

Grâce à la commande + rails generate scaffold +, Rails a généré la plus grande partie du modèle, complétée par un tableau indiquant le champ + body + de chaque message et son + shark + associé.

Ce modèle, tout comme l’autre code que nous avons déjà modifié, considère les publications comme des entités indépendantes, lorsque nous souhaitons utiliser les associations entre nos modèles et les méthodes de collecte et d’aide fournies par ces associations.

Dans le corps de la table, effectuez les mises à jour suivantes:

Commencez par mettre à jour + post.shark + en + post.shark.name +, afin que la table inclue le champ du nom du requin associé, plutôt que d’identifier les informations relatives à l’objet de requin lui-même:

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

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

Ensuite, modifiez la redirection + Show pour diriger les utilisateurs vers la vue` + show s` pour le requin associé, car ils voudront probablement un moyen de revenir au requin d’origine. Nous pouvons utiliser la variable d’instance + @ shark + que nous avons définie dans le contrôleur ici, car Rails rend les variables d’instance créées dans le contrôleur disponibles pour toutes les vues. Nous allons également modifier le texte du lien de + Show à` + Show Shark`, afin que les utilisateurs puissent mieux comprendre sa fonction.

Mettez à jour cette ligne comme suit:

~ / 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>

Dans la ligne suivante, nous voulons nous assurer que les utilisateurs sont routés sur le bon chemin imbriqué lorsqu’ils vont éditer une publication. Cela signifie que plutôt que d’être dirigé vers + posts // edit +, les utilisateurs seront dirigés vers + sharks // posts // edit +. Pour ce faire, nous utiliserons l’assistant de routage + shark_post_path + et nos modèles, que Rails traitera comme des URL. Nous mettrons également à jour le texte du lien pour rendre sa fonction plus claire.

Mettez à jour la ligne + Edit + pour qu’elle ressemble à ce qui suit:

~ / 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>

Ensuite, ajoutons une modification similaire au lien + Destroy +, en mettant à jour sa fonction dans la chaîne et en ajoutant nos ressources + shark + et + post +:

~ / 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>

Enfin, au bas du formulaire, nous voudrons mettre à jour le chemin + New Post + pour amener les utilisateurs vers le chemin imbriqué approprié lorsqu’ils souhaitent créer un nouveau message. Mettez à jour la dernière ligne du fichier pour utiliser l’assistant de routage new_shark_post_path (@shark) +:

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

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

Le fichier fini ressemblera à ceci:

~ / 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) %>

Enregistrez et fermez le fichier une fois l’édition terminée.

Les autres modifications que nous effectuerons pour publier des vues ne seront pas aussi nombreuses, car nos autres vues utilisent le partiel + form + que nous avons déjà modifié. Cependant, nous voudrons mettre à jour les références + link_to + dans les autres modèles de publication pour refléter les modifications que nous avons apportées à notre + formulaire + partiel.

Ouvrez + app / views / posts / new.html.erb +:

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

Mettez à jour la référence + link_to + au bas du fichier pour utiliser l’assistant + shark_posts_path (@shark) +:

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

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

Enregistrez et fermez le fichier lorsque vous avez terminé ces modifications.

Ensuite, ouvrez le template + edit +:

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

En plus du puth + Back, nous mettrons à jour` + How` pour refléter nos ressources imbriquées. Changez les deux dernières lignes du fichier pour ressembler à ceci:

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

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

Enregistrez et fermez le fichier.

Ensuite, ouvrez le template + show +:

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

Effectuez les modifications suivantes sur les chemins + Edit + et + Back + au bas du fichier:

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

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

Enregistrez et fermez le fichier lorsque vous avez terminé.

Enfin, nous voudrons mettre à jour la vue + show + pour nos requins afin que les publications soient visibles pour les requins individuels. Ouvrez ce fichier maintenant:

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

Nos modifications ici incluront l’ajout d’une section + Posts + au formulaire et d’un lien + Add Post + au bas du fichier.

En dessous du + faits + pour un requin donné, nous allons ajouter une nouvelle section qui parcourt chaque instance dans la collection de publications associées à ce requin, en générant le + body + de chaque publication.

Ajoutez le code suivant sous la section + Facts + du formulaire, et au-dessus des redirections au bas du fichier:

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

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








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

Ensuite, ajoutez une nouvelle redirection pour permettre aux utilisateurs d’ajouter une nouvelle publication pour ce requin particulier:

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

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

<%= link_to 'Back', sharks_path %>

Enregistrez et fermez le fichier une fois l’édition terminée.

Vous avez maintenant modifié les modèles, les contrôleurs et les vues de votre application pour vous assurer que les publications sont toujours associées à un requin particulier. Enfin, nous pouvons ajouter des validations à notre modèle `+ Post + 'pour garantir la cohérence des données enregistrées dans la base de données.

Étape 5 - Ajout de validations et test de l’application

Dans Step 5 de Comment construire une application Ruby on Rails, vous avez ajouté des validations à votre modèle + Shark + pour assurer l’uniformité et la cohérence des données qui sont enregistrées dans la base de données + sharks +. Nous allons maintenant prendre une mesure similaire pour garantir également la base de données + posts +.

Ouvrez le fichier où votre modèle + Post + est défini:

nano app/models/post.rb

Ici, nous voulons nous assurer que les publications ne sont pas vierges et qu’elles ne dupliquent pas le contenu que d’autres utilisateurs peuvent avoir posté. Pour ce faire, ajoutez la ligne suivante au fichier:

~ / sharkapp / app / models / post.rb

class Post < ApplicationRecord
 belongs_to :shark

end

Enregistrez et fermez le fichier une fois l’édition terminée.

Avec ce dernier changement en place, vous êtes prêt à exécuter vos migrations et à tester l’application.

Tout d’abord, lancez vos migrations:

rails db:migrate

Ensuite, démarrez votre serveur. Si vous travaillez localement, vous pouvez le faire en lançant:

rails s

Si vous travaillez sur un serveur de développement, exécutez la commande suivante à la place:

rails s --binding=

Accédez à la racine de votre application à + ​​http: // localhost: 3000 + ou + http: //: 3000 +.

Le tutoriel du projet Rails sur les prérequis vous expliquait comment ajouter et modifier une entrée * Grand requin blanc *. Si vous n’avez ajouté aucun autre requin, la page d’arrivée de l’application se présentera comme suit:

image: https: //assets.digitalocean.com/articles/rails_nested_resource/shark_post_landing_2.png [Page de destination de l’application Shark]

Cliquez sur * Show * à côté du nom de * Great White *. Cela vous mènera à la vue + show + pour ce requin. Vous verrez le nom du requin et ses faits, ainsi qu’un en-tête * Posts * sans contenu. Ajoutons un article pour remplir cette partie du formulaire.

Cliquez sur * Ajouter un message * sous l’en-tête * Messages *. Cela vous amènera à la vue «+ index +» du message, où vous aurez la possibilité de sélectionner * Nouveau message *:

image: https: //assets.digitalocean.com/articles/rails_nested_resource/new_post_landing.png [Affichage de l’index post]

Grâce aux mécanismes d’authentification que vous avez mis en place dans https://www.digitalocean.com/community/tutorials/how-to-build-a-ruby-on-rails-application#step-6--%E2%80% 94-ajout-authentification [Étape 6] de Comment créer une application Ruby on Rails, vous pouvez être invité à vous authentifier avec le nom d’utilisateur et le mot de passe que vous avez créés à cette étape, selon que vous ayez ou non créé une nouvelle session.

Cliquez sur * New Post *, ce qui vous amènera à votre post `` new + `template:

image: https: //assets.digitalocean.com/articles/rails_nested_resource/new_post_form.png [Nouveau message]

Dans le champ * Body *, tapez «Ces requins sont effrayants!

image: https: //assets.digitalocean.com/articles/rails_nested_resource/new_shark_post_2.png [Nouveau message sur les requins]

Cliquez sur * Créer un message *. Vous serez redirigé vers la vue + index + pour toutes les publications appartenant à ce requin:

image: https: //assets.digitalocean.com/articles/rails_nested_resource/post_success.png [Post succès]

Maintenant que nos ressources de publication fonctionnent, nous pouvons maintenant tester nos validations de données pour nous assurer que seules les données souhaitées sont enregistrées dans la base de données.

Dans la vue + index +, cliquez sur * Nouveau message *. Dans le champ * Body * du nouveau formulaire, essayez à nouveau d’entrer «Ces requins sont effrayants!»:

image: https: //assets.digitalocean.com/articles/rails_nested_resource/new_shark_post_2.png [Répéter le message de requin]

Cliquez sur * Créer un message *. Vous verrez l’erreur suivante:

image: https: //assets.digitalocean.com/articles/rails_nested_resource/post_unique_error.png [Erreur de publication unique]

Cliquez sur * Retour * pour revenir à la page principale des articles.

Pour tester notre autre validation, cliquez à nouveau sur * New Post *. Laissez le message vide et cliquez sur * Créer un message *. Vous verrez l’erreur suivante:

image: https: //assets.digitalocean.com/articles/rails_nested_resource/post_blank_error.png [Erreur de message vide]

Avec vos ressources et vos validations imbriquées fonctionnant correctement, vous disposez désormais d’une application Rails opérationnelle que vous pouvez utiliser comme point de départ pour un développement ultérieur.

Conclusion

Avec votre application Rails en place, vous pouvez désormais travailler sur des tâches telles que le style et le développement d’autres composants frontaux. Si vous souhaitez en savoir plus sur le routage et les ressources imbriquées, la documentation Rails est un excellent point de départ.

Pour en savoir plus sur l’intégration de frameworks front-end avec votre application, consultez https://www.digitalocean.com/community/tutorials/how-to-set-up-a-ruby-on-rails-project-with -a-react-frontend [Comment configurer un projet Ruby on Rails avec une interface React].