1 Aperçu : Comment les éléments s'assemblent
Ce guide se concentre sur l'interaction entre le contrôleur et la vue dans le triangle Modèle-Vue-Contrôleur. Comme vous le savez, le contrôleur est responsable de l'orchestration de l'ensemble du processus de traitement d'une requête dans Rails, bien qu'il délègue généralement tout code lourd au modèle. Mais ensuite, lorsqu'il est temps d'envoyer une réponse à l'utilisateur, le contrôleur transmet les choses à la vue. C'est cette transmission qui est le sujet de ce guide.
En gros, cela implique de décider ce qui doit être envoyé en tant que réponse et d'appeler une méthode appropriée pour créer cette réponse. Si la réponse est une vue complète, Rails effectue également un travail supplémentaire pour envelopper la vue dans une mise en page et éventuellement pour inclure des vues partielles. Vous verrez tous ces chemins plus tard dans ce guide.
2 Création de réponses
Du point de vue du contrôleur, il existe trois façons de créer une réponse HTTP :
- Appeler
render
pour créer une réponse complète à renvoyer au navigateur. - Appeler
redirect_to
pour envoyer un code d'état de redirection HTTP au navigateur. - Appeler
head
pour créer une réponse composée uniquement d'en-têtes HTTP à renvoyer au navigateur.
2.1 Rendu par défaut : Convention plutôt que configuration en action
Vous avez entendu dire que Rails favorise "la convention plutôt que la configuration". Le rendu par défaut en est un excellent exemple. Par défaut, les contrôleurs dans Rails rendent automatiquement les vues dont les noms correspondent aux routes valides. Par exemple, si vous avez ce code dans votre classe BooksController
:
class BooksController < ApplicationController
end
Et ce qui suit dans votre fichier de routes :
resources :books
Et que vous avez un fichier de vue app/views/books/index.html.erb
:
<h1>Les livres arrivent bientôt !</h1>
Rails rendra automatiquement app/views/books/index.html.erb
lorsque vous accédez à /books
et vous verrez "Les livres arrivent bientôt !" à l'écran.
Cependant, un écran à venir est seulement minimement utile, donc vous allez bientôt créer votre modèle Book
et ajouter l'action index à BooksController
:
class BooksController < ApplicationController
def index
@books = Book.all
end
end
Notez que nous n'avons pas de rendu explicite à la fin de l'action index conformément au principe "la convention plutôt que la configuration". La règle est que si vous ne rendez pas explicitement quelque chose à la fin d'une action de contrôleur, Rails cherchera automatiquement le modèle action_name.html.erb
dans le chemin de vue du contrôleur et le rendra. Donc dans ce cas, Rails rendra le fichier app/views/books/index.html.erb
.
Si nous voulons afficher les propriétés de tous les livres dans notre vue, nous pouvons le faire avec un modèle ERB comme ceci :
<h1>Liste des livres</h1>
<table>
<thead>
<tr>
<th>Titre</th>
<th>Contenu</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% @books.each do |book| %>
<tr>
<td><%= book.title %></td>
<td><%= book.content %></td>
<td><%= link_to "Afficher", book %></td>
<td><%= link_to "Modifier", edit_book_path(book) %></td>
<td><%= link_to "Supprimer", book, data: { turbo_method: :delete, turbo_confirm: "Êtes-vous sûr ?" } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to "Nouveau livre", new_book_path %>
NOTE : Le rendu réel est effectué par des classes imbriquées du module ActionView::Template::Handlers
. Ce guide n'approfondit pas ce processus, mais il est important de savoir que l'extension de fichier de votre vue contrôle le choix du gestionnaire de modèle.
2.2 Utilisation de render
Dans la plupart des cas, la méthode render
du contrôleur effectue le gros du travail de rendu du contenu de votre application pour une utilisation par un navigateur. Il existe plusieurs façons de personnaliser le comportement de render
. Vous pouvez rendre la vue par défaut pour un modèle Rails, ou un modèle spécifique, ou un fichier, ou du code en ligne, ou rien du tout. Vous pouvez rendre du texte, du JSON ou du XML. Vous pouvez également spécifier le type de contenu ou le statut HTTP de la réponse rendue.
CONSEIL : Si vous souhaitez voir les résultats exacts d'un appel à render
sans avoir besoin de l'inspecter dans un navigateur, vous pouvez appeler render_to_string
. Cette méthode prend exactement les mêmes options que render
, mais elle renvoie une chaîne de caractères au lieu d'envoyer une réponse au navigateur.
2.2.1 Rendu de la vue d'une action
Si vous souhaitez rendre la vue correspondant à un autre modèle dans le même contrôleur, vous pouvez utiliser render
avec le nom de la vue :
def update
@book = Book.find(params[:id])
if @book.update(book_params)
redirect_to(@book)
else
render "edit"
end
end
Si l'appel à update
échoue, l'appel de l'action update
dans ce contrôleur rendra le modèle edit.html.erb
appartenant au même contrôleur.
Si vous préférez, vous pouvez utiliser un symbole au lieu d'une chaîne de caractères pour spécifier l'action à rendre :
def update
@book = Book.find(params[:id])
if @book.update(book_params)
redirect_to(@book)
else
render :edit, status: :unprocessable_entity
end
end
2.2.2 Rendu du modèle d'une action à partir d'un autre contrôleur
Que faire si vous souhaitez rendre un modèle à partir d'un contrôleur totalement différent de celui qui contient le code de l'action ? Vous pouvez également le faire avec render
, qui accepte le chemin complet (relatif à app/views
) du modèle à rendre. Par exemple, si vous exécutez du code dans un AdminProductsController
qui se trouve dans app/controllers/admin
, vous pouvez rendre les résultats d'une action vers un modèle dans app/views/products
de cette manière :
render "products/show"
Rails sait que cette vue appartient à un contrôleur différent en raison du caractère de barre oblique intégré dans la chaîne de caractères. Si vous souhaitez être explicite, vous pouvez utiliser l'option :template
(qui était obligatoire dans Rails 2.2 et antérieur) :
render template: "products/show"
2.2.3 Conclusion
Les deux façons de rendre (rendre le modèle d'une autre action dans le même contrôleur et rendre le modèle d'une autre action dans un autre contrôleur) sont en réalité des variantes de la même opération.
En fait, dans la classe BooksController
, à l'intérieur de l'action update
où nous voulons rendre le modèle edit
si le livre ne se met pas à jour avec succès, tous les appels de rendu suivants rendraient tous le modèle edit.html.erb
dans le répertoire views/books
:
render :edit
render action: :edit
render "edit"
render action: "edit"
render "books/edit"
render template: "books/edit"
Lequel vous utilisez est vraiment une question de style et de convention, mais la règle générale est d'utiliser le plus simple qui a du sens pour le code que vous écrivez.
2.2.4 Utilisation de render
avec :inline
La méthode render
peut se passer complètement d'une vue, si vous êtes prêt à utiliser l'option :inline
pour fournir ERB en tant que partie de l'appel de méthode. C'est parfaitement valide :
render inline: "<% products.each do |p| %><p><%= p.name %></p><% end %>"
AVERTISSEMENT : Il y a rarement une bonne raison d'utiliser cette option. Mélanger ERB dans vos contrôleurs contredit l'orientation MVC de Rails et rendra plus difficile pour les autres développeurs de suivre la logique de votre projet. Utilisez plutôt une vue erb séparée.
Par défaut, le rendu en ligne utilise ERB. Vous pouvez le forcer à utiliser Builder avec l'option :type
:
render inline: "xml.p {'Pratique de codage horrible !'}", type: :builder
2.2.5 Rendu de texte
Vous pouvez envoyer du texte brut - sans aucun balisage - au navigateur en utilisant l'option :plain
de render
:
render plain: "OK"
CONSEIL : Le rendu de texte pur est le plus utile lorsque vous répondez à des requêtes Ajax ou de services web qui attendent autre chose que du HTML correct.
REMARQUE : Par défaut, si vous utilisez l'option :plain
, le texte est rendu sans utiliser la mise en page actuelle. Si vous voulez que Rails place le texte dans la mise en page actuelle, vous devez ajouter l'option layout: true
et utiliser l'extension .text.erb
pour le fichier de mise en page.
2.2.6 Rendu de HTML
Vous pouvez envoyer une chaîne HTML au navigateur en utilisant l'option :html
de render
:
render html: helpers.tag.strong('Non trouvé')
CONSEIL : C'est utile lorsque vous rendez un petit extrait de code HTML. Cependant, vous voudrez peut-être le déplacer vers un fichier de modèle si le balisage est complexe.
REMARQUE : Lors de l'utilisation de l'option html:
, les entités HTML seront échappées si la chaîne n'est pas composée avec des API sensibles à html_safe
.
2.2.7 Rendu de JSON
JSON est un format de données JavaScript utilisé par de nombreuses bibliothèques Ajax. Rails prend en charge la conversion d'objets en JSON et le rendu de ce JSON vers le navigateur :
render json: @product
CONSEIL : Vous n'avez pas besoin d'appeler to_json
sur l'objet que vous voulez rendre. Si vous utilisez l'option :json
, render
appellera automatiquement to_json
pour vous.
2.2.8 Rendu XML
Rails dispose également d'une prise en charge intégrée pour convertir des objets en XML et rendre ce XML à l'appelant :
render xml: @product
CONSEIL : Vous n'avez pas besoin d'appeler to_xml
sur l'objet que vous souhaitez rendre. Si vous utilisez l'option :xml
, render
appellera automatiquement to_xml
pour vous.
2.2.9 Rendu JavaScript brut
Rails peut rendre du JavaScript brut :
render js: "alert('Hello Rails');"
Cela enverra la chaîne fournie au navigateur avec un type MIME de text/javascript
.
2.2.10 Rendu du corps brut
Vous pouvez renvoyer un contenu brut au navigateur, sans définir de type de contenu, en utilisant l'option :body
de render
:
render body: "brut"
CONSEIL : Cette option ne doit être utilisée que si vous ne vous souciez pas du type de contenu de la réponse. L'utilisation de :plain
ou :html
est généralement plus appropriée.
REMARQUE : À moins d'être remplacée, votre réponse renvoyée à partir de cette option de rendu sera text/plain
, car c'est le type de contenu par défaut de la réponse de l'action Dispatch.
2.2.11 Rendu de fichier brut
Rails peut rendre un fichier brut à partir d'un chemin absolu. Cela est utile pour rendre conditionnellement des fichiers statiques tels que des pages d'erreur.
render file: "#{Rails.root}/public/404.html", layout: false
Cela rend le fichier brut (il ne prend pas en charge ERB ou d'autres gestionnaires). Par défaut, il est rendu dans la mise en page actuelle.
AVERTISSEMENT : L'utilisation de l'option :file
en combinaison avec l'entrée des utilisateurs peut entraîner des problèmes de sécurité, car un attaquant pourrait utiliser cette action pour accéder à des fichiers sensibles à la sécurité de votre système de fichiers.
CONSEIL : send_file
est souvent une option plus rapide et meilleure si une mise en page n'est pas requise.
2.2.12 Rendu d'objets
Rails peut rendre des objets répondant à :render_in
.
render MyRenderable.new
Cela appelle render_in
sur l'objet fourni avec le contexte de vue actuel.
Vous pouvez également fournir l'objet en utilisant l'option :renderable
de render
:
render renderable: MyRenderable.new
2.2.13 Options pour render
Les appels à la méthode render
acceptent généralement six options :
:content_type
:layout
:location
:status
:formats
:variants
2.2.13.1 L'option :content_type
Par défaut, Rails servira les résultats d'une opération de rendu avec le type de contenu MIME text/html
(ou application/json
si vous utilisez l'option :json
, ou application/xml
pour l'option :xml
). Il peut arriver que vous souhaitiez le modifier, et vous pouvez le faire en définissant l'option :content_type
:
render template: "feed", content_type: "application/rss"
2.2.13.2 L'option :layout
Avec la plupart des options de render
, le contenu rendu est affiché dans le cadre de la mise en page actuelle. Vous en apprendrez plus sur les mises en page et leur utilisation plus tard dans ce guide.
Vous pouvez utiliser l'option :layout
pour indiquer à Rails d'utiliser un fichier spécifique comme mise en page pour l'action actuelle :
render layout: "special_layout"
Vous pouvez également indiquer à Rails de rendre sans aucune mise en page du tout :
render layout: false
2.2.13.3 L'option :location
Vous pouvez utiliser l'option :location
pour définir l'en-tête HTTP Location
:
render xml: photo, location: photo_url(photo)
2.2.13.4 L'option :status
Rails générera automatiquement une réponse avec le code d'état HTTP correct (dans la plupart des cas, il s'agit de 200 OK
). Vous pouvez utiliser l'option :status
pour le modifier :
render status: 500
render status: :forbidden
Rails comprend à la fois les codes d'état numériques et les symboles correspondants indiqués ci-dessous.
Classe de réponse | Code d'état HTTP | Symbole |
---|---|---|
Informationnel | 100 | :continue |
101 | :switching_protocols | |
102 | :processing | |
Succès | 200 | :ok |
201 | :created | |
202 | :accepted | |
203 | :non_authoritative_information | |
204 | :no_content | |
205 | :reset_content | |
206 | :partial_content | |
207 | :multi_status | |
208 | :already_reported | |
226 | :im_used | |
Redirection | 300 | :multiple_choices |
301 | :moved_permanently | |
302 | :found | |
303 | :see_other | |
304 | :not_modified | |
305 | :use_proxy | |
307 | :temporary_redirect | |
308 | :permanent_redirect | |
Erreur client | 400 | :bad_request |
401 | :unauthorized | |
402 | :payment_required | |
403 | :forbidden | |
404 | :not_found | |
405 | :method_not_allowed | |
406 | :not_acceptable | |
407 | :proxy_authentication_required | |
408 | :request_timeout | |
409 | :conflict | |
410 | :gone | |
411 | :length_required | |
412 | :precondition_failed | |
413 | :payload_too_large | |
414 | :uri_too_long | |
415 | :unsupported_media_type | |
416 | :range_not_satisfiable | |
417 | :expectation_failed | |
421 | :misdirected_request | |
422 | :unprocessable_entity | |
423 | :locked | |
424 | :failed_dependency | |
426 | :upgrade_required | |
428 | :precondition_required | |
429 | :too_many_requests | |
431 | :request_header_fields_too_large | |
451 | :unavailable_for_legal_reasons | |
Erreur serveur | 500 | :internal_server_error |
501 | :not_implemented | |
502 | :bad_gateway | |
503 | :service_unavailable | |
504 | :gateway_timeout | |
505 | :http_version_not_supported | |
506 | :variant_also_negotiates | |
507 | :insufficient_storage | |
508 | :loop_detected | |
510 | :not_extended | |
511 | :network_authentication_required |
NOTE : Si vous essayez de rendre du contenu avec un code d'état non-content (100-199, 204, 205 ou 304), il sera supprimé de la réponse.
2.2.13.5 L'option :formats
Rails utilise le format spécifié dans la requête (ou :html
par défaut). Vous pouvez le changer en passant l'option :formats
avec un symbole ou un tableau :
render formats: :xml
render formats: [:json, :xml]
Si un modèle avec le format spécifié n'existe pas, une erreur ActionView::MissingTemplate
est levée.
2.2.13.6 L'option :variants
Cela indique à Rails de rechercher des variations de modèle du même format. Vous pouvez spécifier une liste de variantes en passant l'option :variants
avec un symbole ou un tableau.
Un exemple d'utilisation serait le suivant.
# appelé dans HomeController#index
render variants: [:mobile, :desktop]
Avec cet ensemble de variantes, Rails recherchera l'ensemble de modèles suivant et utilisera le premier qui existe.
app/views/home/index.html+mobile.erb
app/views/home/index.html+desktop.erb
app/views/home/index.html.erb
Si un modèle avec le format spécifié n'existe pas, une erreur ActionView::MissingTemplate
est levée.
Au lieu de définir la variante sur l'appel de rendu, vous pouvez également la définir sur l'objet de requête dans votre action de contrôleur.
def index
request.variant = determine_variant
end
private
def determine_variant
variant = nil
# du code pour déterminer la ou les variantes à utiliser
variant = :mobile if session[:use_mobile]
variant
end
2.2.14 Recherche de mises en page
Pour trouver la mise en page actuelle, Rails recherche d'abord un fichier dans app/views/layouts
avec le même nom de base que le contrôleur. Par exemple, le rendu des actions de la classe PhotosController
utilisera app/views/layouts/photos.html.erb
(ou app/views/layouts/photos.builder
). S'il n'y a pas de mise en page spécifique au contrôleur, Rails utilisera app/views/layouts/application.html.erb
ou app/views/layouts/application.builder
. S'il n'y a pas de mise en page .erb
, Rails utilisera une mise en page .builder
si elle existe. Rails propose également plusieurs façons d'attribuer plus précisément des mises en page spécifiques à des contrôleurs et des actions individuels.
2.2.14.1 Spécification des mises en page pour les contrôleurs
Vous pouvez remplacer les conventions de mise en page par défaut dans vos contrôleurs en utilisant la déclaration layout
. Par exemple :
class ProductsController < ApplicationController
layout "inventory"
#...
end
Avec cette déclaration, toutes les vues rendues par le ProductsController
utiliseront app/views/layouts/inventory.html.erb
comme mise en page.
Pour attribuer une mise en page spécifique à l'ensemble de l'application, utilisez une déclaration de layout
dans votre classe ApplicationController
:
class ApplicationController < ActionController::Base
layout "main"
#...
end
Avec cette déclaration, toutes les vues de l'application utiliseront app/views/layouts/main.html.erb
comme mise en page.
2.2.14.2 Choix des mises en page à l'exécution
Vous pouvez utiliser un symbole pour différer le choix de la mise en page jusqu'à ce qu'une requête soit traitée :
class ProductsController < ApplicationController
layout :products_layout
def show
@product = Product.find(params[:id])
end
private
def products_layout
@current_user.special? ? "special" : "products"
end
end
Maintenant, si l'utilisateur actuel est un utilisateur spécial, il obtiendra une mise en page spéciale lorsqu'il consulte un produit.
Vous pouvez même utiliser une méthode en ligne, telle qu'un Proc, pour déterminer la mise en page. Par exemple, si vous passez un objet Proc, le bloc que vous donnez au Proc recevra l'instance du controller
, de sorte que la mise en page peut être déterminée en fonction de la requête actuelle :
class ProductsController < ApplicationController
layout Proc.new { |controller| controller.request.xhr? ? "popup" : "application" }
end
2.2.14.3 Mises en page conditionnelles
Les mises en page spécifiées au niveau du contrôleur prennent en charge les options :only
et :except
. Ces options prennent soit un nom de méthode, soit un tableau de noms de méthodes, correspondant aux noms de méthodes dans le contrôleur :
class ProductsController < ApplicationController
layout "product", except: [:index, :rss]
end
Avec cette déclaration, la mise en page product
serait utilisée pour tout sauf les méthodes rss
et index
.
2.2.14.4 Héritage des mises en page
Les déclarations de mise en page se propagent vers le bas dans la hiérarchie, et les déclarations de mise en page plus spécifiques l'emportent toujours sur les plus générales. Par exemple :
application_controller.rb
class ApplicationController < ActionController::Base layout "main" end
articles_controller.rb
class ArticlesController < ApplicationController end
special_articles_controller.rb
class SpecialArticlesController < ArticlesController layout "special" end
old_articles_controller.rb
class OldArticlesController < SpecialArticlesController layout false def show @article = Article.find(params[:id]) end def index @old_articles = Article.older render layout: "old" end # ... end
Dans cette application :
- En général, les vues seront rendues dans la mise en page
main
ArticlesController#index
utilisera la mise en pagemain
SpecialArticlesController#index
utilisera la mise en pagespecial
OldArticlesController#show
n'utilisera aucune mise en page du toutOldArticlesController#index
utilisera la mise en pageold
##### Héritage de modèle
Similaire à la logique d'héritage de mise en page, si un modèle ou une partie n'est pas trouvé dans le chemin conventionnel, le contrôleur recherchera un modèle ou une partie à rendre dans sa chaîne d'héritage. Par exemple:
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
end
# app/controllers/admin_controller.rb
class AdminController < ApplicationController
end
# app/controllers/admin/products_controller.rb
class Admin::ProductsController < AdminController
def index
end
end
L'ordre de recherche pour une action admin/products#index
sera:
app/views/admin/products/
app/views/admin/
app/views/application/
Cela fait de app/views/application/
un endroit idéal pour vos parties communes, qui peuvent ensuite être rendues dans votre ERB comme ceci:
<%# app/views/admin/products/index.html.erb %>
<%= render @products || "empty_list" %>
<%# app/views/application/_empty_list.html.erb %>
Il n'y a pas d'éléments dans cette liste <em>encore</em>.
2.2.15 Éviter les erreurs de double rendu
Tôt ou tard, la plupart des développeurs Rails verront le message d'erreur "Can only render or redirect once per action". Bien que cela soit ennuyeux, il est relativement facile à résoudre. Cela se produit généralement en raison d'une incompréhension fondamentale du fonctionnement de render
.
Par exemple, voici du code qui déclenchera cette erreur:
def show
@book = Book.find(params[:id])
if @book.special?
render action: "special_show"
end
render action: "regular_show"
end
Si @book.special?
est évalué à true
, Rails commencera le processus de rendu pour insérer la variable @book
dans la vue special_show
. Mais cela ne stoppera pas le reste du code dans l'action show
et lorsque Rails atteindra la fin de l'action, il commencera à rendre la vue regular_show
- et générera une erreur. La solution est simple: assurez-vous de n'avoir qu'un seul appel à render
ou redirect
dans un seul chemin de code. Une chose qui peut aider est return
. Voici une version corrigée de la méthode:
def show
@book = Book.find(params[:id])
if @book.special?
render action: "special_show"
return
end
render action: "regular_show"
end
Notez que le rendu implicite effectué par ActionController détecte si render
a été appelé, donc le code suivant fonctionnera sans erreur:
def show
@book = Book.find(params[:id])
if @book.special?
render action: "special_show"
end
end
Cela rendra un livre avec special?
défini avec le modèle special_show
, tandis que les autres livres seront rendus avec le modèle show
par défaut.
2.3 Utilisation de redirect_to
Une autre façon de gérer le renvoi des réponses à une requête HTTP est avec redirect_to
. Comme vous l'avez vu, render
indique à Rails quelle vue (ou autre ressource) utiliser pour construire une réponse. La méthode redirect_to
fait quelque chose de complètement différent: elle indique au navigateur d'envoyer une nouvelle requête pour une URL différente. Par exemple, vous pouvez rediriger depuis n'importe quel endroit de votre code vers l'index des photos de votre application avec cet appel:
redirect_to photos_url
Vous pouvez utiliser redirect_back
pour renvoyer l'utilisateur à la page d'où il vient. Cette localisation est extraite de l'en-tête HTTP_REFERER
qui n'est pas garanti d'être défini par le navigateur, vous devez donc fournir la fallback_location
à utiliser dans ce cas.
redirect_back(fallback_location: root_path)
redirect_to
et redirect_back
n'arrêtent pas et ne retournent pas immédiatement de l'exécution de la méthode, mais définissent simplement des réponses HTTP. Les instructions qui se produisent après eux dans une méthode seront exécutées. Vous pouvez arrêter l'exécution par un return
explicite ou un autre mécanisme d'arrêt, si nécessaire.
2.3.1 Obtenir un code d'état de redirection différent
Rails utilise le code d'état HTTP 302, une redirection temporaire, lorsque vous appelez redirect_to
. Si vous souhaitez utiliser un code d'état différent, par exemple 301, une redirection permanente, vous pouvez utiliser l'option :status
:
redirect_to photos_path, status: 301
Tout comme l'option :status
pour render
, :status
pour redirect_to
accepte à la fois des désignations d'en-tête numériques et symboliques.
2.3.2 La différence entre render
et redirect_to
Parfois, les développeurs inexpérimentés considèrent redirect_to
comme une sorte de commande goto
, déplaçant l'exécution d'un endroit à un autre dans votre code Rails. Ce n'est pas correct. Votre code s'arrête et attend une nouvelle requête du navigateur. Il se trouve simplement que vous avez indiqué au navigateur quelle requête il devrait effectuer ensuite, en renvoyant un code d'état HTTP 302.
Considérez ces actions pour voir la différence:
def index
@books = Book.all
end
def show
@book = Book.find_by(id: params[:id])
if @book.nil?
render action: "index"
end
end
Avec le code sous cette forme, il y aura probablement un problème si la variable @book
est nil
. Rappelez-vous, un render :action
n'exécute aucun code dans l'action cible, donc rien ne configurera probablement la variable @books
dont la vue index
aura besoin. Une façon de résoudre ce problème est de rediriger au lieu de rendre:
```ruby
def index
@books = Book.all
end
def show @book = Book.find_by(id: params[:id]) if @book.nil? redirect_to action: :index end end ```
Avec ce code, le navigateur fera une nouvelle demande pour la page d'index, le code dans la méthode index
s'exécutera et tout ira bien.
Le seul inconvénient de ce code est qu'il nécessite un aller-retour vers le navigateur : le navigateur a demandé l'action show avec /books/1
et le contrôleur constate qu'il n'y a pas de livres, donc le contrôleur envoie une réponse de redirection 302 au navigateur lui indiquant d'aller à /books/
, le navigateur obéit et envoie une nouvelle demande au contrôleur demandant maintenant l'action index
, le contrôleur récupère alors tous les livres dans la base de données et rend le modèle index, l'envoyant de nouveau au navigateur qui l'affiche ensuite sur votre écran.
Bien que dans une petite application, cette latence supplémentaire ne pose peut-être pas de problème, il est important d'y penser si le temps de réponse est une préoccupation. Nous pouvons démontrer une façon de gérer cela avec un exemple artificiel :
def index
@books = Book.all
end
def show
@book = Book.find_by(id: params[:id])
if @book.nil?
@books = Book.all
flash.now[:alert] = "Votre livre n'a pas été trouvé"
render "index"
end
end
Cela détecterait qu'il n'y a pas de livres avec l'ID spécifié, remplirait la variable d'instance @books
avec tous les livres du modèle, puis rendrait directement le modèle index.html.erb
, le renvoyant au navigateur avec un message d'alerte flash pour informer l'utilisateur de ce qui s'est passé.
2.4 Utilisation de head
pour construire des réponses avec en-têtes uniquement
La méthode head
peut être utilisée pour envoyer des réponses avec uniquement des en-têtes au navigateur. La méthode head
accepte un nombre ou un symbole (voir tableau de référence) représentant un code d'état HTTP. L'argument des options est interprété comme un hachage de noms et de valeurs d'en-tête. Par exemple, vous pouvez renvoyer uniquement un en-tête d'erreur :
head :bad_request
Cela produirait l'en-tête suivant :
HTTP/1.1 400 Bad Request
Connection: close
Date: Sun, 24 Jan 2010 12:15:53 GMT
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8
X-Runtime: 0.013483
Set-Cookie: _blog_session=...snip...; path=/; HttpOnly
Cache-Control: no-cache
Ou vous pouvez utiliser d'autres en-têtes HTTP pour transmettre d'autres informations :
head :created, location: photo_path(@photo)
Ce qui produirait :
HTTP/1.1 201 Created
Connection: close
Date: Sun, 24 Jan 2010 12:16:44 GMT
Transfer-Encoding: chunked
Location: /photos/1
Content-Type: text/html; charset=utf-8
X-Runtime: 0.083496
Set-Cookie: _blog_session=...snip...; path=/; HttpOnly
Cache-Control: no-cache
3 Structure des mises en page
Lorsque Rails rend une vue en tant que réponse, il le fait en combinant la vue avec la mise en page actuelle, en utilisant les règles de recherche de la mise en page actuelle qui ont été couvertes précédemment dans ce guide. Dans une mise en page, vous avez accès à trois outils pour combiner différents éléments de sortie afin de former la réponse globale :
- Les balises d'actifs
yield
etcontent_for
- Partiels
3.1 Les assistants de balises d'actifs
Les assistants de balises d'actifs fournissent des méthodes pour générer du HTML qui lie des vues à des flux, du JavaScript, des feuilles de style, des images, des vidéos et des fichiers audio. Il existe six assistants de balises d'actifs disponibles dans Rails :
Vous pouvez utiliser ces balises dans des mises en page ou d'autres vues, bien que les balises auto_discovery_link_tag
, javascript_include_tag
et stylesheet_link_tag
soient le plus souvent utilisées dans la section <head>
d'une mise en page.
AVERTISSEMENT : Les assistants de balises d'actifs ne vérifient pas l'existence des ressources aux emplacements spécifiés ; ils supposent simplement que vous savez ce que vous faites et génèrent le lien.
3.1.1 Lien vers des flux avec auto_discovery_link_tag
L'assistant auto_discovery_link_tag
construit du HTML que la plupart des navigateurs et des lecteurs de flux peuvent utiliser pour détecter la présence de flux RSS, Atom ou JSON. Il prend le type de lien (:rss
, :atom
ou :json
), un hachage d'options qui sont transmises à url_for, et un hachage d'options pour la balise :
<%= auto_discovery_link_tag(:rss, {action: "feed"},
{title: "Flux RSS"}) %>
Il existe trois options de balise disponibles pour auto_discovery_link_tag
:
:rel
spécifie la valeurrel
dans le lien. La valeur par défaut est "alternate".:type
spécifie un type MIME explicite. Rails générera automatiquement un type MIME approprié.:title
spécifie le titre du lien. La valeur par défaut est la valeur:type
en majuscules, par exemple, "ATOM" ou "RSS". #### Lien vers des fichiers JavaScript avecjavascript_include_tag
L'aide javascript_include_tag
renvoie une balise HTML script
pour chaque source fournie.
Si vous utilisez Rails avec le pipeline d'actifs activé, cette aide générera un lien vers /assets/javascripts/
plutôt que public/javascripts
qui était utilisé dans les versions précédentes de Rails. Ce lien est ensuite servi par le pipeline d'actifs.
Un fichier JavaScript dans une application Rails ou un moteur Rails se trouve dans l'un des trois emplacements suivants : app/assets
, lib/assets
ou vendor/assets
. Ces emplacements sont expliqués en détail dans la section Organisation des actifs dans le guide du pipeline d'actifs.
Vous pouvez spécifier un chemin complet par rapport à la racine du document, ou une URL, si vous préférez. Par exemple, pour lier à un fichier JavaScript qui se trouve dans un répertoire appelé javascripts
à l'intérieur de app/assets
, lib/assets
ou vendor/assets
, vous feriez ceci :
<%= javascript_include_tag "main" %>
Rails générera alors une balise script
comme ceci :
<script src='/assets/main.js'></script>
La demande de cet actif est ensuite servie par le gem Sprockets.
Pour inclure plusieurs fichiers tels que app/assets/javascripts/main.js
et app/assets/javascripts/columns.js
en même temps :
<%= javascript_include_tag "main", "columns" %>
Pour inclure app/assets/javascripts/main.js
et app/assets/javascripts/photos/columns.js
:
<%= javascript_include_tag "main", "/photos/columns" %>
Pour inclure http://example.com/main.js
:
<%= javascript_include_tag "http://example.com/main.js" %>
3.1.2 Lien vers des fichiers CSS avec stylesheet_link_tag
L'aide stylesheet_link_tag
renvoie une balise HTML <link>
pour chaque source fournie.
Si vous utilisez Rails avec le pipeline d'actifs activé, cette aide générera un lien vers /assets/stylesheets/
. Ce lien est ensuite traité par le gem Sprockets. Un fichier de feuille de style peut être stocké dans l'un des trois emplacements suivants : app/assets
, lib/assets
ou vendor/assets
.
Vous pouvez spécifier un chemin complet par rapport à la racine du document, ou une URL. Par exemple, pour lier à un fichier de feuille de style qui se trouve dans un répertoire appelé stylesheets
à l'intérieur de app/assets
, lib/assets
ou vendor/assets
, vous feriez ceci :
<%= stylesheet_link_tag "main" %>
Pour inclure app/assets/stylesheets/main.css
et app/assets/stylesheets/columns.css
:
<%= stylesheet_link_tag "main", "columns" %>
Pour inclure app/assets/stylesheets/main.css
et app/assets/stylesheets/photos/columns.css
:
<%= stylesheet_link_tag "main", "photos/columns" %>
Pour inclure http://example.com/main.css
:
<%= stylesheet_link_tag "http://example.com/main.css" %>
Par défaut, stylesheet_link_tag
crée des liens avec rel="stylesheet"
. Vous pouvez remplacer cette valeur par défaut en spécifiant une option appropriée (:rel
) :
<%= stylesheet_link_tag "main_print", media: "print" %>
3.1.3 Lien vers des images avec image_tag
L'aide image_tag
construit une balise HTML <img />
pour le fichier spécifié. Par défaut, les fichiers sont chargés à partir de public/images
.
AVERTISSEMENT : Notez que vous devez spécifier l'extension de l'image.
<%= image_tag "header.png" %>
Vous pouvez fournir un chemin vers l'image si vous le souhaitez :
<%= image_tag "icons/delete.gif" %>
Vous pouvez fournir un hachage d'options HTML supplémentaires :
<%= image_tag "icons/delete.gif", {height: 45} %>
Vous pouvez fournir un texte alternatif pour l'image qui sera utilisé si l'utilisateur a désactivé les images dans son navigateur. Si vous ne spécifiez pas de texte alternatif explicitement, il sera par défaut le nom du fichier, en majuscules et sans extension. Par exemple, ces deux balises d'image renverraient le même code :
<%= image_tag "home.gif" %>
<%= image_tag "home.gif", alt: "Home" %>
Vous pouvez également spécifier une balise de taille spéciale, au format "{largeur}x{hauteur}" :
<%= image_tag "home.gif", size: "50x20" %>
En plus des balises spéciales ci-dessus, vous pouvez fournir un hachage final d'options HTML standard, telles que :class
, :id
ou :name
:
<%= image_tag "home.gif", alt: "Go Home",
id: "HomeImage",
class: "nav_bar" %>
3.1.4 Lien vers des vidéos avec video_tag
L'aide video_tag
construit une balise HTML5 <video>
pour le fichier spécifié. Par défaut, les fichiers sont chargés à partir de public/videos
.
<%= video_tag "movie.ogg" %>
Produit
<video src="/videos/movie.ogg" />
Comme avec image_tag
, vous pouvez fournir un chemin, soit absolu, soit relatif au répertoire public/videos
. De plus, vous pouvez spécifier l'option size: "#{largeur}x#{hauteur}"
comme avec image_tag
. Les balises vidéo peuvent également avoir l'une des options HTML spécifiées à la fin (id
, class
, etc.).
La balise vidéo prend également en charge toutes les options HTML <video>
, y compris :
poster: "nom_image.png"
, fournit une image à afficher à la place de la vidéo avant qu'elle ne commence à jouer.autoplay: true
, lance la lecture de la vidéo au chargement de la page.loop: true
, boucle la vidéo une fois qu'elle atteint la fin.controls: true
, fournit des contrôles fournis par le navigateur pour que l'utilisateur interagisse avec la vidéo.autobuffer: true
, la vidéo préchargera le fichier pour l'utilisateur au chargement de la page. Vous pouvez également spécifier plusieurs vidéos à lire en passant un tableau de vidéos à la balisevideo_tag
:
<%= video_tag ["trailer.ogg", "movie.ogg"] %>
Cela produira :
<video>
<source src="/videos/trailer.ogg">
<source src="/videos/movie.ogg">
</video>
3.1.5 Lien vers des fichiers audio avec la balise audio_tag
L'aide audio_tag
construit une balise HTML5 <audio>
pour le fichier spécifié. Par défaut, les fichiers sont chargés à partir de public/audios
.
<%= audio_tag "music.mp3" %>
Vous pouvez fournir un chemin vers le fichier audio si vous le souhaitez :
<%= audio_tag "music/first_song.mp3" %>
Vous pouvez également fournir un hachage d'options supplémentaires, telles que :id
, :class
, etc.
Comme la balise video_tag
, la balise audio_tag
a des options spéciales :
autoplay: true
, commence à lire l'audio lors du chargement de la pagecontrols: true
, fournit des contrôles fournis par le navigateur pour que l'utilisateur interagisse avec l'audio.autobuffer: true
, l'audio préchargera le fichier pour l'utilisateur lors du chargement de la page.
3.2 Comprendre yield
Dans le contexte d'une mise en page, yield
identifie une section où le contenu de la vue doit être inséré. La manière la plus simple d'utiliser cela est d'avoir un seul yield
, dans lequel l'ensemble du contenu de la vue en cours de rendu est inséré :
<html>
<head>
</head>
<body>
<%= yield %>
</body>
</html>
Vous pouvez également créer une mise en page avec plusieurs régions de rendu :
<html>
<head>
<%= yield :head %>
</head>
<body>
<%= yield %>
</body>
</html>
Le corps principal de la vue sera toujours rendu dans le yield
sans nom. Pour rendre du contenu dans un yield
nommé, vous utilisez la méthode content_for
.
3.3 Utilisation de la méthode content_for
La méthode content_for
vous permet d'insérer du contenu dans un bloc yield
nommé de votre mise en page. Par exemple, cette vue fonctionnerait avec la mise en page que vous venez de voir :
<% content_for :head do %>
<title>Une page simple</title>
<% end %>
<p>Bonjour, Rails !</p>
Le résultat du rendu de cette page dans la mise en page fournie serait le HTML suivant :
<html>
<head>
<title>Une page simple</title>
</head>
<body>
<p>Bonjour, Rails !</p>
</body>
</html>
La méthode content_for
est très utile lorsque votre mise en page contient des régions distinctes telles que des barres latérales et des pieds de page qui doivent recevoir leurs propres blocs de contenu insérés. Elle est également utile pour insérer des balises qui chargent des fichiers JavaScript ou CSS spécifiques à une page dans l'en-tête d'une mise en page générique.
3.4 Utilisation de Partials
Les modèles partiels - généralement appelés simplement "partials" - sont un autre moyen de diviser le processus de rendu en morceaux plus gérables. Avec un partiel, vous pouvez déplacer le code de rendu d'une partie spécifique d'une réponse vers son propre fichier.
3.4.1 Nommer les Partials
Pour rendre un partiel dans une vue, vous utilisez la méthode render
dans la vue :
<%= render "menu" %>
Cela rendra un fichier nommé _menu.html.erb
à cet endroit dans la vue en cours de rendu. Notez le caractère de soulignement initial : les partiels sont nommés avec un soulignement initial pour les distinguer des vues régulières, même s'ils sont référencés sans le soulignement. Cela est également vrai lorsque vous importez un partiel à partir d'un autre dossier :
<%= render "shared/menu" %>
Ce code importera le partiel depuis app/views/shared/_menu.html.erb
.
3.4.2 Utilisation de Partials pour simplifier les vues
Une façon d'utiliser les partiels est de les considérer comme l'équivalent de sous-routines : comme un moyen de déplacer les détails d'une vue afin de mieux comprendre ce qui se passe. Par exemple, vous pourriez avoir une vue qui ressemble à ceci :
<%= render "shared/ad_banner" %>
<h1>Produits</h1>
<p>Voici quelques-uns de nos excellents produits :</p>
...
<%= render "shared/footer" %>
Ici, les partiels _ad_banner.html.erb
et _footer.html.erb
pourraient contenir du contenu partagé par de nombreuses pages de votre application. Vous n'avez pas besoin de voir les détails de ces sections lorsque vous vous concentrez sur une page particulière.
Comme on l'a vu dans les sections précédentes de ce guide, yield
est un outil très puissant pour nettoyer vos mises en page. Gardez à l'esprit que c'est du pur Ruby, vous pouvez donc l'utiliser presque partout. Par exemple, nous pouvons l'utiliser pour rendre les définitions de mise en page de formulaire DRY pour plusieurs ressources similaires :
users/index.html.erb
<%= render "shared/search_filters", search: @q do |form| %> <p> Le nom contient : <%= form.text_field :name_contains %> </p> <% end %>
roles/index.html.erb
<%= render "shared/search_filters", search: @q do |form| %> <p> Le titre contient : <%= form.text_field :title_contains %> </p> <% end %>
shared/_search_filters.html.erb
<%= form_with model: search do |form| %> <h1>Formulaire de recherche :</h1> <fieldset> <%= yield form %> </fieldset> <p> <%= form.submit "Rechercher" %> </p> <% end %>
CONSEIL : Pour le contenu partagé entre toutes les pages de votre application, vous pouvez utiliser des partiels directement à partir des mises en page.
3.4.3 Mises en page partielles
Un partiel peut utiliser son propre fichier de mise en page, tout comme une vue peut utiliser une mise en page. Par exemple, vous pouvez appeler un partiel de cette manière :
<%= render partial: "zone_lien", layout: "barre_grise" %>
Cela rechercherait un partiel nommé _zone_lien.html.erb
et le rendrait en utilisant la mise en page _barre_grise.html.erb
. Notez que les mises en page pour les partiels suivent le même nom avec un trait de soulignement en tête que les partiels réguliers, et sont placées dans le même dossier que le partiel auquel elles appartiennent (pas dans le dossier principal layouts
).
Notez également que spécifier explicitement :partial
est nécessaire lors de la transmission d'options supplémentaires telles que :layout
.
3.4.4 Transmission de variables locales
Vous pouvez également transmettre des variables locales aux partiels, ce qui les rend encore plus puissants et flexibles. Par exemple, vous pouvez utiliser cette technique pour réduire la duplication entre les pages de création et de modification, tout en conservant un peu de contenu distinct :
new.html.erb
<h1>Nouvelle zone</h1> <%= render partial: "formulaire", locals: {zone: @zone} %>
edit.html.erb
<h1>Modification de la zone</h1> <%= render partial: "formulaire", locals: {zone: @zone} %>
_formulaire.html.erb
<%= form_with model: zone do |form| %> <p> <b>Nom de la zone</b><br> <%= form.text_field :name %> </p> <p> <%= form.submit %> </p> <% end %>
Bien que le même partiel soit rendu dans les deux vues, l'aide à la soumission de Action View renverra "Créer la zone" pour l'action de création et "Mettre à jour la zone" pour l'action de modification.
Pour transmettre une variable locale à un partiel uniquement dans des cas spécifiques, utilisez local_assigns
.
index.html.erb
<%= render user.articles %>
show.html.erb
<%= render article, full: true %>
_article.html.erb
<h2><%= article.title %></h2> <% if local_assigns[:full] %> <%= simple_format article.body %> <% else %> <%= truncate article.body %> <% end %>
De cette façon, il est possible d'utiliser le partiel sans avoir besoin de déclarer toutes les variables locales.
Chaque partiel a également une variable locale portant le même nom que le partiel (moins le trait de soulignement initial). Vous pouvez transmettre un objet à cette variable locale via l'option :object
:
<%= render partial: "client", object: @nouveau_client %>
Dans le partiel client
, la variable client
fera référence à @nouveau_client
de la vue parente.
Si vous avez une instance d'un modèle à rendre dans un partiel, vous pouvez utiliser une syntaxe abrégée :
<%= render @client %>
En supposant que la variable d'instance @client
contient une instance du modèle Client
, cela utilisera _client.html.erb
pour le rendre et passera la variable locale client
dans le partiel qui fera référence à la variable d'instance @client
dans la vue parente.
3.4.5 Rendu de collections
Les partiels sont très utiles pour le rendu de collections. Lorsque vous transmettez une collection à un partiel via l'option :collection
, le partiel sera inséré une fois pour chaque élément de la collection :
index.html.erb
<h1>Produits</h1> <%= render partial: "produit", collection: @produits %>
_produit.html.erb
<p>Nom du produit : <%= produit.name %></p>
Lorsqu'un partiel est appelé avec une collection au pluriel, les instances individuelles du partiel ont accès à l'élément de la collection qui est rendu via une variable portant le nom du partiel. Dans ce cas, le partiel est _produit
, et dans le partiel _produit
, vous pouvez vous référer à produit
pour obtenir l'instance qui est rendue.
Il existe également une syntaxe abrégée pour cela. En supposant que @produits
est une collection d'instances de Produit
, vous pouvez simplement écrire ceci dans index.html.erb
pour obtenir le même résultat :
<h1>Produits</h1>
<%= render @produits %>
Rails détermine le nom du partiel à utiliser en examinant le nom du modèle dans la collection. En fait, vous pouvez même créer une collection hétérogène et la rendre de cette façon, et Rails choisira le partiel approprié pour chaque élément de la collection :
index.html.erb
<h1>Contacts</h1> <%= render [client1, employe1, client2, employe2] %>
clients/_client.html.erb
<p>Client : <%= client.name %></p>
employes/_employe.html.erb
<p>Employé : <%= employe.name %></p>
Dans ce cas, Rails utilisera les partiels client
ou employe
selon le cas pour chaque élément de la collection.
Dans le cas où la collection est vide, render
renverra nil, il devrait donc être assez simple de fournir un contenu alternatif.
<h1>Produits</h1>
<%= render(@products) || "Il n'y a aucun produit disponible." %>
3.4.6 Variables locales
Pour utiliser un nom de variable locale personnalisé dans la partial, spécifiez l'option :as
dans l'appel à la partial :
<%= render partial: "product", collection: @products, as: :item %>
Avec ce changement, vous pouvez accéder à une instance de la collection @products
en tant que variable locale item
dans la partial.
Vous pouvez également passer des variables locales arbitraires à n'importe quelle partial que vous affichez avec l'option locals: {}
:
<%= render partial: "product", collection: @products,
as: :item, locals: {title: "Page des produits"} %>
Dans ce cas, la partial aura accès à une variable locale title
avec la valeur "Page des produits".
3.4.7 Variables de compteur
Rails met également à disposition une variable de compteur dans une partial appelée par la collection. La variable est nommée d'après le nom de la partial suivi de _counter
. Par exemple, lors de l'affichage d'une collection @products
, la partial _product.html.erb
peut accéder à la variable product_counter
. La variable indexe le nombre de fois que la partial a été affichée dans la vue englobante, en commençant par une valeur de 0
lors du premier affichage.
# index.html.erb
<%= render partial: "product", collection: @products %>
# _product.html.erb
<%= product_counter %> # 0 pour le premier produit, 1 pour le deuxième produit...
Cela fonctionne également lorsque le nom de la partial est modifié à l'aide de l'option as:
. Ainsi, si vous avez fait as: :item
, la variable de compteur serait item_counter
.
3.4.8 Modèles d'espacement
Vous pouvez également spécifier une deuxième partial à afficher entre les instances de la partial principale en utilisant l'option :spacer_template
:
<%= render partial: @products, spacer_template: "product_ruler" %>
Rails affichera la partial _product_ruler
(sans données transmises) entre chaque paire de partials _product
.
3.4.9 Mises en page de partials de collection
Lors de l'affichage de collections, il est également possible d'utiliser l'option :layout
:
<%= render partial: "product", collection: @products, layout: "special_layout" %>
La mise en page sera affichée avec la partial pour chaque élément de la collection. Les variables d'objet actuel et d'objet_counter seront également disponibles dans la mise en page, de la même manière qu'elles le sont dans la partial.
3.5 Utilisation de mises en page imbriquées
Il se peut que votre application nécessite une mise en page légèrement différente de votre mise en page d'application habituelle pour prendre en charge un contrôleur particulier. Au lieu de répéter la mise en page principale et de la modifier, vous pouvez le faire en utilisant des mises en page imbriquées (parfois appelées sous-modèles). Voici un exemple :
Supposons que vous ayez la mise en page suivante pour ApplicationController
:
app/views/layouts/application.html.erb
<html> <head> <title><%= @page_title or "Titre de la page" %></title> <%= stylesheet_link_tag "layout" %> <style><%= yield :stylesheets %></style> </head> <body> <div id="top_menu">Éléments du menu supérieur ici</div> <div id="menu">Éléments du menu ici</div> <div id="content"><%= content_for?(:content) ? yield(:content) : yield %></div> </body> </html>
Sur les pages générées par NewsController
, vous souhaitez masquer le menu supérieur et ajouter un menu droit :
app/views/layouts/news.html.erb
<% content_for :stylesheets do %> #top_menu {display: none} #right_menu {float: right; background-color: yellow; color: black} <% end %> <% content_for :content do %> <div id="right_menu">Éléments du menu droit ici</div> <%= content_for?(:news_content) ? yield(:news_content) : yield %> <% end %> <%= render template: "layouts/application" %>
C'est tout. Les vues News utiliseront la nouvelle mise en page, masquant le menu supérieur et ajoutant un nouveau menu droit à l'intérieur de la div "content".
Il existe plusieurs façons d'obtenir des résultats similaires avec différents schémas de sous-modèles en utilisant cette technique. Notez qu'il n'y a pas de limite dans les niveaux d'imbrication. On peut utiliser la méthode ActionView::render
via render template: 'layouts/news'
pour baser une nouvelle mise en page sur la mise en page News. Si vous êtes sûr de ne pas utiliser de sous-modèle pour la mise en page News
, vous pouvez remplacer content_for?(:news_content) ? yield(:news_content) : yield
simplement par yield
.
Retour d'information
Vous êtes encouragé à contribuer à l'amélioration de la qualité de ce guide.
Veuillez contribuer si vous trouvez des fautes de frappe ou des erreurs factuelles. Pour commencer, vous pouvez lire notre contribution à la documentation section.
Vous pouvez également trouver du contenu incomplet ou des informations qui ne sont pas à jour. Veuillez ajouter toute documentation manquante pour la version principale. Assurez-vous de vérifier Edge Guides d'abord pour vérifier si les problèmes ont déjà été résolus ou non sur la branche principale. Consultez les Directives des guides Ruby on Rails pour le style et les conventions.
Si pour une raison quelconque vous repérez quelque chose à corriger mais ne pouvez pas le faire vous-même, veuillez ouvrir un problème.
Et enfin, toute discussion concernant la documentation de Ruby on Rails est la bienvenue sur le Forum officiel de Ruby on Rails.