ビューとヘルパー
Ruby on Rails
ERB・パーシャル・レイアウト・form_with
ERB テンプレート
タグの種類・パーシャル・レイアウト
<%# ERB タグの種類 %>
<% code %> <%# 実行(出力なし)%>
<%= expression %> <%# 実行して出力(エスケープあり)%>
<%== raw_html %> <%# 実行して出力(エスケープなし)%>
<%- trimmed -%> <%# 前後の空白・改行を削除 %>
<%# ループ %>
<% @posts.each do |post| %>
<article>
<h2><%= post.title %></h2>
<p><%= post.body.truncate(200) %></p>
<time><%= post.created_at.strftime('%Y年%m月%d日') %></time>
<%# リンクヘルパー %>
<%= link_to '詳細', post_path(post), class: 'btn' %>
<%= link_to '削除', post_path(post),
method: :delete,
data: { turbo_confirm: '削除しますか?' },
class: 'btn btn-danger' %>
</article>
<% end %>
<%# 条件分岐 %>
<% if @post.published? %>
<span class="badge">公開済み</span>
<% elsif @post.draft? %>
<span class="badge">下書き</span>
<% end %>
<%# パーシャルの呼び出し %>
<%= render 'shared/header' %>
<%= render partial: 'post', locals: { post: @post } %>
<%= render @posts %> <%# コレクションの自動レンダリング %>
<%= render @posts, cached: true %> <%# キャッシュ付き %>
<%# コンテンツのキャプチャ %>
<% content_for :title do %>
<%= @post.title %> | MyBlog
<% end %>
<%# ヘルパーメソッド %>
<%= number_with_delimiter(1000000) %> <%# 1,000,000 %>
<%= time_ago_in_words(@post.created_at) %> <%# 3分前 %>
<%= truncate(@post.body, length: 100) %>
<%= pluralize(@post.comments.count, 'comment') %>レイアウトとパーシャル
yield・content_for・パーシャルのパターン
<!DOCTYPE html>
<html lang="ja">
<head>
<title><%= content_for?(:title) ? yield(:title) : 'MyApp' %></title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag 'application', media: 'all' %>
<%= javascript_importmap_tags %>
</head>
<body class="<%= body_class %>">
<header>
<%= render 'shared/navbar' %>
<%= render 'shared/flash_messages' %>
</header>
<main>
<%= yield %> <%# 各ページのコンテンツ %>
</main>
<%# 複数の yield ゾーン %>
<%= yield :sidebar if content_for?(:sidebar) %>
<%= yield :modal %>
<%= render 'shared/footer' %>
</body>
</html>パーシャルのパターン
<%# app/views/posts/_post.html.erb %>
<%# render @posts → 各 post に対してこのパーシャルを自動呼び出し %>
<article id="<%= dom_id(post) %>" class="post">
<h3><%= link_to post.title, post %></h3>
<p><%= post.excerpt %></p>
<%# ネストしたパーシャル %>
<%= render 'tags/tag', collection: post.tags, as: :tag %>
</article>
<%# フォームパーシャル(new と edit で共有)%>
<%# app/views/posts/_form.html.erb %>
<%= form_with model: post do |f| %>
<div class="field">
<%= f.label :title %>
<%= f.text_field :title, class: 'form-control' %>
<% if post.errors[:title].any? %>
<span class="error"><%= post.errors[:title].first %></span>
<% end %>
</div>
<div class="field">
<%= f.label :body %>
<%= f.text_area :body, rows: 10 %>
</div>
<div class="field">
<%= f.select :status, Post.statuses.keys, include_blank: '選択してください' %>
</div>
<div class="field">
<%= f.collection_check_boxes :tag_ids, Tag.all, :id, :name %>
</div>
<%= f.submit '保存', class: 'btn btn-primary' %>
<% end %>ヘルパーメソッド
form_with・link_to・image_tag・カスタムヘルパー
<%# === フォームヘルパー === %>
<%= form_with model: @user, url: users_path do |f| %>
<%= f.text_field :name, placeholder: '名前', autofocus: true %>
<%= f.email_field :email %>
<%= f.password_field :password %>
<%= f.number_field :age, min: 0, max: 150 %>
<%= f.check_box :active %>
<%= f.radio_button :role, 'admin' %> 管理者
<%= f.radio_button :role, 'user' %> 一般ユーザー
<%= f.select :role, [['管理者', 'admin'], ['一般', 'user']] %>
<%= f.file_field :avatar, accept: 'image/*' %>
<%= f.hidden_field :token, value: form_token %>
<%= f.submit '登録' %>
<% end %>
<%# 検索フォーム(モデルに対応しない)%>
<%= form_with url: search_path, method: :get do |f| %>
<%= f.search_field :q, placeholder: '検索...' %>
<%= f.submit '検索' %>
<% end %>
<%# === リンクとURL === %>
<%= link_to '詳細', @post %>
<%= link_to '編集', edit_post_path(@post) %>
<%= link_to '↗外部', 'https://example.com', target: '_blank', rel: 'noopener' %>
<%= button_to '削除', @post, method: :delete, data: { confirm: '本当に?' } %>
<%# === 画像・アセット === %>
<%= image_tag 'logo.png', alt: 'ロゴ', width: 100 %>
<%= image_tag @user.avatar, class: 'avatar' if @user.avatar.attached? %>
<%= stylesheet_link_tag 'print', media: 'print' %>
<%# === 数値・日時 === %>
<%= number_to_currency(1234.5, unit: '¥', precision: 0) %> <%# ¥1,235 %>
<%= number_to_percentage(75.4, precision: 1) %> <%# 75.4% %>
<%= number_with_delimiter(1000000) %> <%# 1,000,000 %>
<%= distance_of_time_in_words(from, to) %>
<%= @post.created_at.strftime('%Y年%m月%d日 %H:%M') %>