Introduction
Ruby on Rails est un framework d’application web écrit en Ruby qui offre aux développeurs une approche opinionnée du développement d’applications. Travailler avec Rails offre aux développeurs :
- Des conventions pour gérer des éléments tels que le routage, les données étatiques et la gestion des ressources.
- 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.
A mesure que vous ajoutez de la complexité à vos applications Rails, vous travaillerez probablement avec plusieurs modèles, qui représentent la logique métier de votre application et interagissent avec votre base de données. Ajouter des modèles liés signifie établir des relations significatives entre eux, ce qui affecte ensuite la façon dont les informations sont relayées à travers les contrôleurs de votre application, et comment elles sont capturées et présentées aux utilisateurs à travers les vues.
Dans ce tutoriel, vous construirez sur une application Rails existante qui offre aux utilisateurs des faits sur les requins. Cette application a déjà un modèle pour gérer les données sur les requins, mais vous ajouterez une ressource imbriquée pour les publications sur les requins individuels. Cela permettra aux utilisateurs d’élaborer un corpus plus large de réflexions et d’opinions sur les requins individuels.
Prérequis
Pour suivre ce tutoriel, vous aurez besoin de :
- 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 et npm installés sur votre machine locale ou serveur de développement. Ce tutoriel utilise la version de Node.js 10.16.3 et la version de npm 6.9.0. Pour des conseils sur l’installation de Node.js et npm sur Ubuntu 18.04, suivez les instructions de la section « Installation en utilisant un PPA » de Comment Installer Node.js sur Ubuntu 18.04.
- Ruby, rbenv, et Rails installés sur votre machine locale ou serveur de développement, en suivant les étapes 1 à 4 dans Comment Installer Ruby on Rails avec rbenv sur Ubuntu 18.04. Ce tutoriel utilise Ruby 2.5.1, rbenv 1.1.2, et Rails 5.2.3.
- SQLite installé, et une application d’informations de base sur les requins créée, en suivant les instructions de Comment Construire une Application Ruby on Rails.
Étape 1 — Création du Modèle Emboîté
Notre application tirera parti des associations d’Active Record pour établir une relation entre les modèles Shark
et Post
: les posts appartiendront à des requins particuliers, et chaque requin pourra avoir plusieurs posts. Nos modèles Shark
et Post
seront donc reliés par les associations belongs_to
et has_many
.
La première étape pour développer l’application de cette manière sera de créer un modèle Post
et les ressources associées. Pour cela, nous pouvons utiliser la commande rails generate scaffold
, qui nous fournira un modèle, une migration de base de données pour modifier le schéma de la base de données, un contrôleur, un ensemble complet de vues pour gérer les opérations standard de Création, Lecture, Mise à jour, et Suppression (CRUD), et des modèles pour les partiels, les aides et les tests. Nous devrons modifier ces ressources, mais utiliser la commande scaffold
nous fera gagner du temps et de l’énergie puisqu’elle génère une structure que nous pouvons utiliser comme point de départ.
Assurez-vous d’abord que vous êtes dans le répertoire sharkapp
du projet Rails que vous avez créé dans les prérequis :
Créez vos ressources Post
avec la commande suivante :
rails generate scaffold Post body:text shark:references
Avec body:text
, nous disons à Rails d’inclure un champ body
dans la table de base de données posts
– la table qui est associée au modèle Post
. Nous incluons également le mot-clé :references
, qui établit une association entre les modèles Shark
et Post
. Plus précisément, cela garantira qu’une clé étrangère représentant chaque entrée de requin dans la base de données sharks
soit ajoutée à la base de données posts
.
Une fois que vous avez exécuté la commande, vous verrez une sortie confirmant les ressources générées par Rails pour l’application. Avant de continuer, vous pouvez vérifier le fichier de migration de votre base de données pour examiner la relation qui existe désormais entre vos modèles et les tables de base de données. Utilisez la commande suivante pour consulter le contenu du fichier, en veillant à remplacer le timestamp de votre propre fichier de migration par ce qui est indiqué ici :
Vous verrez la sortie suivante :
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
Comme vous pouvez le voir, la table inclut une colonne pour une clé étrangère de requin. Cette clé prendra la forme de nom_du_modèle_id
– dans notre cas, shark_id
.
Rails a également établi la relation entre les modèles ailleurs. Jetez un œil au modèle Post
nouvellement généré avec la commande suivante :
cat app/models/post.rb
Outputclass Post < ApplicationRecord
belongs_to :shark
end
L’association belongs_to
é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 application, cela signifie qu’un seul post appartient à un seul requin.
En plus d’établir cette relation, la commande rails generate scaffold
a également créé des routes et des vues pour les publications, tout comme elle l’a fait pour nos ressources shark dans Étape 3 de Comment construire une application Ruby on Rails.
C’est un bon début, mais nous devrons configurer quelques routes supplémentaires et consolider l’association Active Record pour le modèle Shark
afin que la relation entre nos modèles et routes fonctionne comme souhaité.
Étape 2 — Spécification des routes imbriquées et des associations pour le modèle parent
Rails a déjà défini l’association belongs_to
dans notre modèle Post
, grâce au mot-clé :references
dans la commande rails generate scaffold
, mais pour que cette relation fonctionne correctement, nous devrons spécifier une association has_many
dans notre modèle Shark
également. Nous devrons également apporter des modifications au routage par défaut que Rails nous a donné afin de faire des ressources post des enfants des ressources shark.
Pour ajouter l’association has_many
au modèle Shark
, ouvrez app/models/shark.rb
en utilisant nano
ou votre éditeur préféré :
Ajoutez la ligne suivante au fichier pour établir la relation entre les requins et les posts :
class Shark < ApplicationRecord
has_many :posts
validates :name, presence: true, uniqueness: true
validates :facts, presence: true
end
Une chose à considérer ici est ce qui arrive aux posts une fois qu’un requin particulier est supprimé. Nous ne voulons probablement pas que les posts associés à un requin supprimé persistent dans la base de données. Pour garantir que tous les posts associés à un requin donné sont éliminés lorsque ce requin est supprimé, nous pouvons inclure l’option dependent
avec l’association.
Ajoutez le code suivant au fichier pour garantir que l’action destroy
sur un requin donné supprime tous les posts associés :
class Shark < ApplicationRecord
has_many :posts , dependent: :destroy
validates :name, presence: true, uniqueness: true
validates :facts, presence: true
end
Une fois que vous avez terminé ces modifications, 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 ressources :
Actuellement, le fichier ressemble à ceci :
Rails.application.routes.draw do
resources :posts
resources :sharks
root 'sharks#index'
# Pour plus de détails sur le DSL disponible dans ce fichier, consultez http://guides.rubyonrails.org/routing.html
end
Le code actuel établit une relation indépendante entre nos routes, alors que ce que nous aimerions exprimer est une relation dépendante entre les requins et leurs posts associés.
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 :
Rails.application.routes.draw do
resources :sharks do
resources :posts
end
root 'sharks#index'
# Pour plus de détails sur le DSL disponible dans ce fichier, consultez http://guides.rubyonrails.org/routing.html
end
Enregistrez et fermez le fichier lorsque vous avez fini d’éditer.
Avec ces modifications en place, vous pouvez passer à la mise à jour de votre contrôleur posts
.
Étape 3 — Mise à jour du contrôleur de messages
L’association entre nos modèles nous donne des méthodes que nous pouvons utiliser pour créer de nouvelles instances de postes associées à des requins particuliers. Pour utiliser ces méthodes, nous devrons les ajouter à notre contrôleur de messages.
Ouvrez le fichier du contrôleur de messages:
Actuellement, le fichier ressemble à ceci :
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
# OBTENIR /messages
# OBTENIR /messages.json
def index
@posts = Post.all
end
# OBTENIR /messages/1
# OBTENIR /messages/1.json
def show
end
# OBTENIR /messages/new
def new
@post = Post.new
end
# OBTENIR /messages/1/edit
def edit
end
# POSTER /messages
# POSTER /messages.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
# PATCHER /messages/1
# PATCHER /messages/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
# SUPPRIMER /messages/1
# SUPPRIMER /messages/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
# Utilisez des rappels pour partager une configuration ou des contraintes communes entre les actions.
def set_post
@post = Post.find(params[:id])
end
# Ne faites jamais confiance aux paramètres provenant d'Internet, autorisez uniquement la liste blanche à travers.
def post_params
params.require(:post).permit(:body, :shark_id)
end
end
Comme notre contrôleur de requêtes, les méthodes de ce contrôleur travaillent avec des instances de la classe de Message
associée. Par exemple, la méthode nouveau
crée une nouvelle instance de la classe Message
, la méthode index
récupère toutes les instances de la classe, et la méthode set_message
utilise find
et params
pour sélectionner un message particulier par id
. Toutefois, si nous voulons que nos instances de message soient associées à des instances de requête particulières, nous devrons modifier ce code, car la classe Message
fonctionne actuellement comme une entité indépendante.
Nos modifications utiliseront deux choses :
- Les méthodes qui sont devenues disponibles pour nous lorsque nous avons ajouté les associations
belongs_to
ethas_many
à nos modèles. En particulier, nous avons maintenant accès à la méthodebuild
grâce à l’associationhas_many
que nous avons définie dans notre modèleShark
. Cette méthode nous permettra de créer une collection d’objets de publication associés à un objet requin particulier, en utilisant la clé étrangèreshark_id
qui existe dans notre base de donnéesposts
. - Les routes et les aides au routage qui sont devenues disponibles lorsque nous avons créé une route
posts
imbriquée. Pour une liste complète des routes d’exemple qui deviennent disponibles lorsque vous créez des relations imbriquées entre les ressources, consultez la documentation Rails. Pour l’instant, il nous suffira de savoir que pour chaque requin spécifique — disonssharks/1
— il y aura une route associée pour les publications liées à ce requin :sharks/1/posts
. Il y aura également des aides au routage commeshark_posts_path(@shark)
etedit_sharks_posts_path(@shark)
qui font référence à ces routes imbriquées.
Dans le fichier, nous commencerons par écrire une méthode, get_shark
, qui s’exécutera avant chaque action dans le contrôleur. Cette méthode créera une variable d’instance locale @shark
en trouvant une instance de requin par shark_id
. Avec cette variable disponible pour nous dans le fichier, il sera possible de relier des 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:
. . .
private
def get_shark
@shark = Shark.find(params[:shark_id])
end
# Utilisez des rappels pour partager les configurations ou contraintes communes entre les actions.
. . .
Ensuite, ajoutez le filtre correspondant en haut du fichier, avant le filtre existant:
class PostsController < ApplicationController
before_action :get_shark
Cela garantira que get_shark
s’exécute 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 post associées à une instance de requin particulière.
Modifiez la méthode index
comme ceci:
. . .
def index
@posts = @shark.posts
end
. . .
La méthode new
nécessitera une révision similaire, car nous voulons qu’une nouvelle instance de post soit associée à un requin particulier. Pour ce faire, nous pouvons utiliser la méthode build
, ainsi que notre variable d’instance locale @shark
.
Modifiez la méthode new
comme ceci:
. . .
def new
@post = @shark.posts.build
end
. . .
Cette méthode crée un objet post associé à l’instance spécifique de requin provenant 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 post en utilisant les paramètres que les utilisateurs ont saisis dans le formulaire new
, et, s’il n’y a pas d’erreurs, elle enregistre cette instance et utilise un assistant de route pour rediriger les utilisateurs là où ils peuvent voir le nouveau post. En cas d’erreurs, elle rend à nouveau le modèle new
.
Mettez à jour la méthode create
pour ressembler à ceci :
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
Ensuite, jetez un œil à 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 ?
Jetez un œil aux filtres en haut du fichier. Le deuxième filtre before_action
auto-généré fournit une réponse :
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
à partir de la méthode set_post
. Cette méthode, répertoriée sous la méthode get_shark
avec nos autres méthodes private
, ressemble actuellement à ceci :
. . .
private
. . .
def set_post
@post = Post.find(params[:id])
end
. . .
En accord avec les 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 dans la collection de publications qui est associée à un requin particulier. Gardez à l’esprit la méthode build
ici – grâce aux associations entre nos modèles, et les méthodes (comme build
) qui sont disponibles pour nous en vertu de ces associations, chacune de nos instances de publication fait partie d’une collection d’objets qui est associée à un requin particulier. Il est donc logique que lors de la requête d’une publication particulière, nous requérions la collection de publications associée à un requin particulier.
Met à jour set_post
pour ressembler à ceci :
. . .
private
. . .
def set_post
@post = @shark.posts.find(params[:id])
end
. . .
Au lieu de trouver une instance particulière de toute la classe Post
par id
, nous recherchons plutôt un id
correspondant dans la collection de publications associée à 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 saisis 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’erreurs, Rails rendra à nouveau le modèle edit
.
Dans ce cas, le seul changement que nous devrons apporter est à l’instruction redirect_to
, pour gérer les mises à jour réussies. Mettez à jour pour rediriger vers shark_post_path(@shark)
, ce qui redirigera vers la vue index
des publications du requin sélectionné :
. . .
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
. . .
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 :
. . .
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
. . .
C’est le dernier changement que nous ferons. Vous avez maintenant un fichier de contrôleur de publications qui ressemble à ceci :
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
# Utilisez des rappels pour partager des configurations ou des contraintes communes entre les actions.
def set_post
@post = @shark.posts.find(params[:id])
end
# Ne faites jamais confiance aux paramètres de l'internet effrayant, autorisez uniquement la liste blanche.
def post_params
params.require(:post).permit(:body, :shark_id)
end
end
Le contrôleur gère comment les informations sont transmises des modèles de vue à la base de données et vice versa. 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, où les utilisateurs passeront et modifieront les informations sur les publications concernant des requins particuliers.
Étape 4 — Modification des vues
Nos révisions de modèles de vue impliqueront de modifier les modèles qui concernent les publications, et également de modifier notre vue show
des requins, car nous voulons 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:
Plutôt que de transmettre uniquement le modèle post
à l’assistant de formulaire form_with
, nous transmettrons à la place les modèles shark
et post
, avec post
défini comme une ressource enfant.
Modifiez la première ligne du fichier pour ressembler à ceci, reflétant la relation entre nos ressources shark et post:
<%= form_with(model: [@shark, post], local: true) do |form| %>
. . .
Ensuite, supprimez la section qui répertorie l’id du shark
lié, car ce n’est pas une information essentielle dans la vue.
Le formulaire fini, avec nos modifications à la première ligne et sans la section shark_id
supprimée, ressemblera à ceci:
<%= 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 lorsque vous avez terminé les modifications.
Ensuite, ouvrez la vue index
, qui affichera les articles associés à un requin particulier:
Grâce à la commande rails generate scaffold
, Rails a généré la majeure partie du modèle, avec une table qui montre le champ body
de chaque article et son shark
associé.
Cependant, tout comme le reste du code que nous avons déjà modifié, ce modèle traite les articles comme des entités indépendantes, alors que nous aimerions utiliser les associations entre nos modèles et les collections et méthodes d’aide que ces associations nous donnent.
Dans le corps de la table, effectuez les mises à jour suivantes:
Tout d’abord, mettez à jour post.shark
en post.shark.name
, afin que la table inclue le champ de nom du requin associé, plutôt que des informations d’identification sur l’objet requin lui-même:
. . .
<tbody>
<% @posts.each do |post| %>
<tr>
<td><%= post.body %></td>
<td><%= post.shark.name %></td>
. . .
Ensuite, modifiez la redirection de Show
pour diriger les utilisateurs vers la vue show
pour le requin associé, car ils voudront très probablement un moyen de revenir au requin original. Nous pouvons utiliser la variable d’instance @shark
que nous avons définie dans le contrôleur ici, puisque Rails rend les variables d’instance créées dans le contrôleur disponibles pour toutes les vues. Nous changerons également le texte du lien de Show
à Show Shark
, afin que les utilisateurs comprennent mieux sa fonction.
Met à jour cette ligne comme suit:
. . .
<tbody>
<% @posts.each do |post| %>
<tr>
<td><%= post.body %></td>
<td><%= post.shark.name %></td>
<td><%= link_to 'Show Shark', [@shark] %></td>
Dans la ligne suivante, nous voulons nous assurer que les utilisateurs sont dirigés vers le bon chemin imbriqué lorsqu’ils vont modifier un post. Cela signifie qu’au lieu d’être dirigés vers posts/post_id/edit
, les utilisateurs seront dirigés vers sharks/shark_id/posts/post_id/edit
. Pour cela, 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.
Met à jour la ligne Edit
pour ressembler à ce qui suit:
. . .
<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>
Ensuite, ajoutons un changement similaire au lien Destroy
, en mettant à jour sa fonction dans la chaîne, et en ajoutant nos ressources shark
et post
:
. . .
<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>
Enfin, en bas du formulaire, nous voudrons mettre à jour le chemin de New Post
pour emmener les utilisateurs vers le chemin imbriqué approprié lorsqu’ils veulent créer un nouveau post. Mettez à jour la dernière ligne du fichier pour utiliser l’assistant de routage new_shark_post_path(@shark)
:
. . .
<%= link_to 'New Post', new_shark_post_path(@shark) %>
Le fichier fini ressemblera à ceci:
<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 lorsque vous avez terminé d’éditer.
Les autres modifications que nous apporterons aux vues des publications ne seront pas aussi nombreuses, car nos autres vues utilisent la partial form
que nous avons déjà éditée. Cependant, nous voudrons mettre à jour les références link_to
dans les autres modèles de publication pour refléter les changements apportés à notre partial form
.
Ouvrez app/views/posts/new.html.erb
:
Mettez à jour la référence link_to
en bas du fichier pour utiliser l’assistant shark_posts_path(@shark)
:
. . .
<%= link_to 'Back', shark_posts_path(@shark) %>
Enregistrez et fermez le fichier lorsque vous avez terminé de faire cette modification.
Ensuite, ouvrez le modèle edit
:
En plus du chemin Retour
, nous mettrons à jour Afficher
pour refléter nos ressources imbriquées. Modifiez les deux dernières lignes du fichier pour ressembler à ceci :
. . .
<%= link_to 'Show', [@shark, @post] %> |
<%= link_to 'Back', shark_posts_path(@shark) %>
Enregistrez et fermez le fichier.
Ensuite, ouvrez le modèle show
:
nano app/views/posts/show.html.erb
Apportez les modifications suivantes aux chemins Modifier
et Retour
en bas du fichier :
. . .
<%= link_to 'Edit', edit_shark_post_path(@shark, @post) %> |
<%= link_to 'Back', shark_posts_path(@shark) %>
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 :
Nos modifications ici incluront l’ajout d’une section Publications
au formulaire et un lien Ajouter une publication
en bas du fichier.
Ci-dessous les Faits
pour un requin donné, nous ajouterons une nouvelle section qui itère à travers chaque instance dans la collection de publications associées à ce requin, en affichant le corps
de chaque publication.
Ajoutez le code suivant sous la section Faits
du formulaire, et au-dessus des redirections en bas du fichier:
. . .
<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) %> |
. . .
Ensuite, ajoutez une nouvelle redirection pour permettre aux utilisateurs d’ajouter une nouvelle publication pour ce requin particulier:
. . .
<%= link_to 'Edit', edit_shark_path(@shark) %> |
<%= link_to 'Add Post', shark_posts_path(@shark) %> |
<%= link_to 'Back', sharks_path %>
Enregistrez et fermez le fichier lorsque vous avez fini d’éditer.
Vous avez maintenant apporté des modifications aux modèles, contrôleurs et vues de votre application pour garantir que les publications sont toujours associées à un requin particulier. En guise de dernière étape, nous pouvons ajouter quelques 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 Étape 5 de Comment construire une application Ruby on Rails, vous avez ajouté des validations à votre modèle Shark
pour garantir l’uniformité et la cohérence des données enregistrées dans la base de données sharks
. Nous allons maintenant faire une étape similaire pour garantir des garanties pour la base de données posts
également.
Ouvrez le fichier où votre modèle Post
est défini :
Ici, nous voulons nous assurer que les publications ne sont pas vides et qu’elles ne dupliquent pas le contenu d’autres utilisateurs. Pour ce faire, ajoutez la ligne suivante au fichier :
class Post < ApplicationRecord
belongs_to :shark
validates :body, presence: true, uniqueness: true
end
Enregistrez et fermez le fichier lorsque vous avez terminé d’éditer.
Avec ce dernier changement en place, vous êtes prêt à exécuter vos migrations et à tester l’application.
Tout d’abord, exécutez vos migrations :
Ensuite, démarrez votre serveur. Si vous travaillez en local, vous pouvez le faire en exécutant :
Si vous travaillez sur un serveur de développement, exécutez plutôt la commande suivante :
Accédez à la racine de votre application à l’adresse http://localhost:3000
ou http://your_server_ip:3000
.
Le tutoriel sur le projet Rails préalable vous a guidé à travers l’ajout et la modification d’une entrée de requin Grand Requin Blanc. Si vous n’avez pas ajouté d’autres requins, la page d’accueil de l’application ressemblera à ceci :
Cliquez sur Afficher à côté du nom du Grand Blanc. 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 Publications sans contenu. Ajoutons un post pour peupler cette partie du formulaire.
Cliquez sur Ajouter une publication en dessous de l’en-tête Publications. Cela vous amènera à la vue de l’index des publications, où vous aurez la possibilité de sélectionner Nouvelle publication:
Grâce aux mécanismes d’authentification que vous avez mis en place à l’étape 6 de Comment construire une application Ruby on Rails, il se peut que vous soyez 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 Nouvelle publication, ce qui vous amènera à votre modèle new
de publication:
Dans le champ Corps, tapez : « Ces requins sont effrayants ! »
Cliquez sur Créer une publication. Vous serez redirigé vers la vue index
pour toutes les publications appartenant à ce requin:
Avec nos ressources de publication fonctionnant, 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.
Depuis la vue index
, cliquez sur Nouvelle publication. Dans le champ Corps du nouveau formulaire, essayez de saisir à nouveau « Ces requins sont effrayants ! »
Cliquez sur Créer un message. Vous verrez l’erreur suivante :
Cliquez sur Retour pour revenir à la page principale des messages.
Pour tester une autre validation, cliquez à nouveau sur Nouveau message. Laissez le message vide et cliquez sur Créer un message. Vous verrez l’erreur suivante :
Avec vos ressources imbriquées et vos validations fonctionnant correctement, vous disposez maintenant d’une application Rails fonctionnelle que vous pouvez utiliser comme point de départ pour un développement ultérieur.
Conclusion
Avec votre application Rails en place, vous pouvez maintenant travailler sur des éléments tels que le style et le développement d’autres composants côté front-end. 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 frontaux avec votre application, consultez Comment configurer un projet Ruby on Rails avec un frontend React.