Section 13.5.2 : Views, partials et helpers
🎯 Objectif pédagogique
Maîtriser le système de vues Rails (ERB), les partials pour la réutilisation, les helpers pour la logique de présentation, et les layouts pour la structure globale des pages.
ERB : Embedded Ruby
ERB est le moteur de templates par défaut de Rails. Il mélange HTML et Ruby :
<!-- app/views/articles/index.html.erb -->
<h1>Articles</h1>
<% @articles.each do |article| %>
<div class="card mb-3">
<div class="card-body">
<h2><%= article.title %></h2>
<p><%= truncate(article.content, length: 200) %></p>
<% if article.published? %>
<span class="badge bg-success">Publié</span>
<% else %>
<span class="badge bg-warning">Brouillon</span>
<% end %>
<p class="text-muted">
Publié le <%= article.created_at.strftime('%d/%m/%Y') %>
</p>
<%= link_to 'Lire', article_path(article), class: 'btn btn-primary' %>
</div>
</div>
<% end %>
Syntaxe ERB :
- →
<% code %>— exécute du Ruby (pas d'affichage) - →
<%= expression %>— exécute et affiche le résultat - →
<%# commentaire %>— commentaire (non affiché)
Layouts
Le layout est le squelette HTML qui entoure chaque vue :
<!-- app/views/layouts/application.html.erb -->
<!DOCTYPE html>
<html>
<head>
<title><%= content_for?(:title) ? yield(:title) : 'MonApp' %></title>
<%= csrf_meta_tags %>
<%= stylesheet_link_tag 'application' %>
<%= javascript_include_tag 'application', defer: true %>
</head>
<body>
<%= render 'shared/navbar' %>
<% if notice %>
<div class="alert alert-success alert-dismissible fade show">
<%= notice %>
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
<% end %>
<main class="container py-4">
<%= yield %>
</main>
<%= render 'shared/footer' %>
</body>
</html>
Partials : la réutilisation
Les partials sont des fragments de vue réutilisables. Leur nom commence par un underscore :
<!-- app/views/articles/_article.html.erb (partial) -->
<div class="card mb-3" id="<%= dom_id(article) %>">
<div class="card-body">
<h3><%= link_to article.title, article %></h3>
<p><%= truncate(article.content, length: 150) %></p>
<small class="text-muted"><%= time_ago_in_words(article.created_at) %></small>
</div>
</div>
<!-- Utilisation dans index.html.erb -->
<%= render @articles %>
<!-- Rails devine automatiquement qu il faut utiliser _article.html.erb -->
<!-- Ou explicitement -->
<%= render partial: 'article', collection: @articles %>
<!-- Partial avec variables locales -->
<%= render 'shared/sidebar', title: 'Navigation', links: @nav_links %>
Formulaires Rails
<!-- app/views/articles/_form.html.erb -->
<%= form_with(model: article, class: 'needs-validation') do |f| %>
<% if article.errors.any? %>
<div class="alert alert-danger">
<h4><%= pluralize(article.errors.count, 'erreur') %></h4>
<ul>
<% article.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="mb-3">
<%= f.label :title, class: 'form-label' %>
<%= f.text_field :title, class: 'form-control' %>
</div>
<div class="mb-3">
<%= f.label :content, class: 'form-label' %>
<%= f.text_area :content, class: 'form-control', rows: 10 %>
</div>
<div class="mb-3 form-check">
<%= f.check_box :published, class: 'form-check-input' %>
<%= f.label :published, 'Publier', class: 'form-check-label' %>
</div>
<%= f.submit class: 'btn btn-primary' %>
<% end %>
Helpers
Les helpers contiennent la logique de présentation à réutiliser dans les vues :
# app/helpers/articles_helper.rb
module ArticlesHelper
def status_badge(article)
if article.published?
content_tag(:span, 'Publié', class: 'badge bg-success')
else
content_tag(:span, 'Brouillon', class: 'badge bg-warning')
end
end
def reading_time(article)
words = article.content.split.size
minutes = (words / 200.0).ceil
"#{minutes} min de lecture"
end
end
<!-- Utilisation dans la vue -->
<%= status_badge(@article) %>
<span><%= reading_time(@article) %></span>
Quelle est la convention de nommage pour un partial Rails ?
Learn AI, from prompts to agents